EntityManager.merge()
新しいオブジェクトを挿入したり、既存のオブジェクトを更新したりできます。
persist()
(新しいオブジェクトを作成することしかできない) をなぜ使用する必要があるのでしょうか?
ベストアンサー1
どちらの方法でもエンティティが PersistenceContext に追加されますが、違いはその後エンティティに対して行う操作にあります。
Persist はエンティティ インスタンスを取得し、それをコンテキストに追加して、そのインスタンスを管理対象にします (つまり、エンティティに対する将来の更新が追跡されます)。
Merge は、状態がマージされたマネージド インスタンスを返します。PersistenceContext に存在するものを返すか、エンティティの新しいインスタンスを作成します。いずれの場合も、指定されたエンティティから状態をコピーし、マネージド コピーを返します。渡したインスタンスはマネージドではありません (merge を再度呼び出さない限り、行った変更はトランザクションの一部にはなりません)。ただし、返されたインスタンス (マネージド インスタンス) を使用することはできます。
コード例が役立つかもしれません。
MyEntity e = new MyEntity();
// scenario 1
// tran starts
em.persist(e);
e.setSomeField(someValue);
// tran ends, and the row for someField is updated in the database
// scenario 2
// tran starts
e = new MyEntity();
em.merge(e);
e.setSomeField(anotherValue);
// tran ends but the row for someField is not updated in the database
// (you made the changes *after* merging)
// scenario 3
// tran starts
e = new MyEntity();
MyEntity e2 = em.merge(e);
e2.setSomeField(anotherValue);
// tran ends and the row for someField is updated
// (the changes were made to e2, not e)
シナリオ 1 と 3 はほぼ同等ですが、シナリオ 2 を使用する必要がある状況もあります。