JPA EntityManager: merge() ではなく persist() を使用する理由 質問する

JPA EntityManager: merge() ではなく persist() を使用する理由 質問する

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 を使用する必要がある状況もあります。

おすすめ記事