2012-11-18 4 views
13

質問はDoctirneについてですが、私はそれが多くのORMに拡張できると思います。ORMにエンティティを分離してマージする必要があるのはなぜですか?

デタッチ:

エンティティは、EntityManagerのから取り外さず、従ってもはやその上にまたはそれに切り離し操作をカスケード によってEntityManager#detach($entity)メソッドを呼び出すことによって を管理されています。デタッチされた エンティティ(エンティティの削除を含む)に加えられた変更は、エンティティがデタッチされた後で がデータベースに同期されません。

マージ:

マージエンティティは、彼らが再び を管理なるようにするEntityManagerのコンテキストに(通常はデタッチ)エンティティ のマージを指します。エンティティの状態をEntityManagerにマージするには、 EntityManager#merge($entity)メソッドを使用します。渡されたエンティティ の状態は、このエンティティのマネージドコピーにマージされ、このコピーはその後 が返されます。

私は(ほぼ)これがどのように機能するのか理解していますが、質問は次のとおりです。エントリーの分離/マージが必要な理由は何ですか?これらの2つの操作を使用/必要にすることができる場合の例/シナリオを教えてください。

答えて

14

いつエンティティを切り離す必要がありますか?
EM(EntityManagerのは)広く複数のEMに対処し、例えば同時実行の競合を回避するときに使用されてから実体を取り外す:

$user= $em->find('models\User', 1); 
$user->setName('Foo'); 

// You can not remove this user, 
// because it still attached to the first Entity Manager 
$em2->remove($user); 
$em2->flush(); 

ので、あなたが$em2によって$userオブジェクトの制御を取ることができませんそのセッションは、最初に$userをデータベースからロードする$emに属します。それらの問題を解決する方法は?あなたは、オブジェクトをデタッチする必要があります。

$user= $em->find('models\User', 1); 
$user->setName('Foo'); 

$em2->detach($user); 
$em2->remove($user); 
$em2->flush(); 

私は機能をマージ使用すべきですか? EMは、メモリ内の$ユーザ対データベースで$ユーザーの間で比較されます

$user= $em->find('models\User', 1); 
$user->setName('Foo'); 

$em->merge($user); 
$em->flush(); 


は、基本的には、エンティティを更新したいとき。 EMが変更されたフィールドを認識すると、EMだけが更新され、古いフィールドが保持されます。

flush方法がトリガーコミットし、ユーザー名は、データベースの同時実行の問題を扱うときは、実体を切り離す必要があるだろう

+0

です言ったことを除いて言ったフラッシュについて。 flushメソッドは、エンティティをデータベースと同期させますが、トランザクションの境界内で同期します。これは、まったく同じトランザクション内でクエリを呼び出すときに再生されます。したがって、クエリの処理でこの非常にトランザクションの更新が考慮されることを確認できます。 – Sam

+0

あなたは正しいです@サム、私はフラッシュメソッドに間違っていた。 – manix

+1

これは良い説明(+1)ですが、最初に複数のエンティティマネージャを使用する理由は何ですか? Doctrineを常に1つのエンティティマネージャで使用すると申し訳ありません。 – gremo

1

に更新されます。

プロジェクトにコールバックを行う非同期APIを使用しているとします。コールバック命令と共にAPIコールを発行すると、コールバックの影響を受けるエンティティをまだ管理している可能性があり、コールバックによって加えられた変更を上書きする可能性があります。

-1

データベース内のデータを壊れたときにエンティティを切り離すこともできますが、コード内ではユーザーアカウントに応じてこのエンティティを変更します。

たとえば、いくつかのキャラクターといくつかの攻撃を行うゲームがあります。 (90 LVL)「UserFoo」により使用さAttackOneは「UserBarr」(LVL 20)で使用されるよりも、より良いボーナスによって変更されますが、私達のデータベースAttackOneにすべての時間は、私はすべてに同意する同じ攻撃

関連する問題