2011-08-31 10 views
7

私はDoctrine 2を自分のORMとして使用していますが、状況は順調ですが、私はEntityManager#persist()メソッドについて疑問に思っています。 "Persisting entities"ドキュメントオブジェクトXためpersist()への呼び出しについては、次の言葉:いつ呼び出すかを知っている

Xは既存の管理対象エンティティである場合、それは持続操作によって無視されます。

これは、persist()がオブジェクトが新規であり、まだデータベースに保存されていない場合にのみ呼び出す必要があると私に導きます。しかし、"Deferred Explicit" change tracking policyのドキュメントは言う:

...ドクトリン2のみのEntityManagerの呼び出し#存続(エンティティ)を介して明示的変化検出のためにマークされているエンティティを考えて...

... persist()のような音は、それが全く更新されないようにオブジェクト上で呼び出さなければなりません。いつpersist()を呼び出す必要がありますか?新しいオブジェクトだけの場合は、エンティティが更新されるたびにそれを呼び出すための有意義なパフォーマンスヒットがあり、Doctrineにその違いを整理させますか?

答えて

8

Deferred Explicit policy(これはデフォルトポリシーではありません)では、doctrineが変更された各エンティティに対してpersistent()を明示的に呼び出して永続化する必要があります。

Doctrineは、更新するプロパティを知るために各プロパティの新しい値と元の値を比較する必要があります。persist()が多すぎると、パフォーマンスが低下する可能性があります。

default change tracking policyでは、まだDoctrineによって管理されていないエンティティ(newで作成したエンティティ)に対してのみpersistを呼び出す必要があります。このポリシーでは、flush()を呼び出すと、doctrineはどのエンティティが更新され、永続化する必要があるかを自動的に検出します。

+0

遅延暗黙の変更トラッキング(デフォルト)を使用すると、Doctrineは、UnitOfWork内にあるすべてのエンティティについて、元の値とすべてのプロパティの新しい値(これまではDeferred Explicitと同じ)を比較しますあなたが 'persist()'と呼んでいるものです。 –

+3

デフォルトポリシーがDeferred Explicitポリシーであると考えられて問題が発生するまでの半分の人生が生きています。 –

6

文書は多少誤解を招きます。暗黙追跡モードでは、すべてのエンティティに状態(管理、削除、分離など)があります。 find()と同様の方法(基本的にはnewで作成されていないもの)で取得されたエンティティは、すでに管理状態になっています。 flush()では、管理された(削除された)すべてのエンティティの変更がチェックされ、必要に応じてDB内で更新されます。

明示的な追跡モードでは、追加のダーティチェックリストがあり、persist()は、オブジェクト(カスケード設定に応じて関連する可能性のあるオブジェクト)をそのリストに追加します。ダーティチェックリストの項目のみが更新対象とみなされます。ダーティチェックリストはフラッシュ後にクリアされるので、2回目のフラッシュを実行して同じオブジェクトを再度変更する場合は、もう一度persist()と呼ぶ必要があります。対照的に、管理された状態はフラッシュ後に保持されます。

Doctrine\ORM\UnitOfWorkクラスで詳細を確認できます。 isChangeTrackingDeferredImplicit/isChangeTrackingDeferredExplicit(これらは2つのポリシーの下で動作が異なる唯一の場所です)を検索してください。

+0

私は、データテーブルに影響を与えるだけのデータを追加する必要がある、キャッシュされた結果セットから分離されたエンティティ(チャネル)を持っています。切り離されたチャンネルをマージせずにチャンネルのデータを保持する方法はありますか? – andig

+0

@andig、わからない私はそれについて話している[この質問](http://stackoverflow.com/questions/18102728/doctrine-persisting-detached-entities) - なぜあなたは本当にちょうど追加したいときにチャネルを維持する必要がありますか新しいデータエンティティ? – Tgr

+0

優秀な質問です。私はレガシーコードで作業しており、Doctrineについてはまだ新しいです。私は直接 'データ'のArrayCollectionを永続化することができるかどうかを調べます。働いていれば私は投票できるので相互回答に感謝します。 – andig

関連する問題