1. ホーム
  2. java

[解決済み] JPAとHibernateのpersist()とmerge()の違いは何ですか?

2022-08-11 06:42:59

質問

Hibernateのpersist()とmerge()の違いは何ですか?

persist() はUPDATE & INSERTクエリを作成することができます、例えば。

SessionFactory sef = cfg.buildSessionFactory();
Session session = sef.openSession();
A a=new A();
session.persist(a);
a.setName("Mario");
session.flush();

この場合 クエリ はこのように生成されます。

Hibernate: insert into A (NAME, ID) values (?, ?)
Hibernate: update A set NAME=? where ID=?

だから persist() メソッドは を生成します。 を生成します。

では merge() :

SessionFactory sef = cfg.buildSessionFactory();
Session session = sef.openSession();
Singer singer = new Singer();
singer.setName("Luciano Pavarotti");
session.merge(singer);
session.flush();

データベースにはこのように表示されています。

SINGER_ID   SINGER_NAME
1           Ricky Martin
2           Madonna
3           Elvis Presley
4           Luciano Pavarotti

では、レコードを更新するには merge()

SessionFactory sef = cfg.buildSessionFactory();
Session session = sef.openSession();
Singer singer = new Singer();
singer.setId(2);
singer.setName("Luciano Pavarotti");
session.merge(singer);
session.flush();

データベースにはこのように表示されています。

SINGER_ID   SINGER_NAME
1           Ricky Martin
2           Luciano Pavarotti
3           Elvis Presley

どのように解決するのですか?

JPA仕様 には、これらの操作のセマンティクスに関する非常に正確な記述があり、javadocよりも優れています。

のセマンティクスは を持続させる 操作をエンティティXに適用した場合のセマンティクスは である。

  • Xが新しいエンティティである場合、それは が管理されるようになります。エンティティXは トランザクションコミット時またはその前にデータベースに トランザクションコミットまたは フラッシュ操作の結果としてデータベースに入力されます。

  • もしXが が既存のマネージドエンティティである場合、それは persist オペレーションによって無視されます。 しかし、persist操作は はXによって参照されるエンティティにカスケードされる。 Xからこれらのエンティティへの関係が 他のエンティティへの関係が cascade=PERSIST または cascade=ALL アノテーション要素の値、または と等価なXML記述子 要素で指定されます。

  • Xが削除されたエンティティである場合。 は管理されるようになります。

  • もしXが を切り離した場合 EntityExistsException が投げられるかもしれません。 がスローされます。 あるいは EntityExistsException または 別の PersistenceException が投げられるかもしれません。 はフラッシュ時やコミット時に投げられます。

  • に対して によって参照されるすべてのエンティティYが Xからのリレーションシップによって参照されるすべてのエンティティYについて、もし Yへのリレーションシップがアノテーションされている場合 カスケード要素の値で cascade=PERSIST または cascade=ALL であれば の場合,Yにpersist操作が適用される。


のセマンティクスは マージ 操作 をエンティティXに適用した場合のセマンティクスは以下の通りである。

  • Xがデタッチドエンティティである場合、Xの状態 Xの状態が既存の の管理下エンティティインスタンスX'にコピーされる。 またはXの新しい管理されたコピーX' が作成されます。

  • Xが新しいエンティティ インスタンスである場合、新しい管理対象エンティティ インスタンスX'が作成され、Xの状態が Xの状態が新しいマネージドエンティティインスタンスX' にコピーされる。 エンティティインスタンスX'にコピーされます。

  • もしXが 削除されたエンティティインスタンスであれば IllegalArgumentException が投げられます。 が投げられる(または、トランザクションのコミットが失敗する)。 トランザクションコミットが失敗します)。

  • もしX が管理されたエンティティである場合、それはマージ操作によって無視されます。 は無視されますが にカスケードされます。 関係によって参照されるエンティティ Xからの関係によって参照されるエンティティにカスケードされます。 でアノテーションされている場合、マージ操作はX からの関係によって参照されるエンティティにカスケードされます。 要素値 cascade=MERGE または cascade=ALL のアノテーションを使用します。

  • すべての 関係によって参照されるすべてのエンティティY カスケード要素を持つXからの 値 cascade=MERGE または cascade=ALL , Y はY'として再帰的にマージされる。Xによって参照されるすべての Xによって参照されるすべてのそのようなYに対して、X'は を参照するように設定される。(ただし、Xが が管理されている場合、Xは X'.)

  • XがX'にマージされたエンティティである場合、X', を、別のエンティティYへの参照とする。 ここで cascade=MERGE または cascade=ALL が指定されていない場合 が指定されていない場合、X'からの同じアソシエーションのナビゲーションは X'から同じアソシエーションのナビゲーションを行うと を持つマネージドオブジェクトY'への参照が得られる。 への参照が生成されます。