1. ホーム
  2. jpa

[解決済み] JPA EntityManager。なぜmerge()ではなくpersist()を使うのか?

2022-03-19 09:13:04

質問

EntityManager.merge() は、新しいオブジェクトを挿入したり、既存のオブジェクトを更新することができます。

なぜ persist() (新しいオブジェクトを作ることしかできない)?

解決方法は?

どちらの方法でも、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を使いたい状況もあります。