1

JPA を使用しています (JPA プロバイダーとして Hibernate を使用)。エンティティを削除する操作があり、エンティティをデタッチしてすぐにマージすると、例外がスローされるようです。

em.find(entity.class, entitiy.getId())
em.detach(entity)
em.merge(entity)   

単純にエラーが発生します

em.find(entity.class, entitiy.getId())

無事通過します。デタッチとマージに関して欠けているものはありますか? エンティティ自体には何もしませんでした。それは変更されていないため、マージによって何も変更されないはずです。

必要に応じて、特定のケースについて詳しく説明できます。

編集

@rmertins が指摘したように、マージからの戻り値を使用する必要がありました。パラメーターとして使用したエンティティは切り離されたまま、マージはマージ エンティティを返すためです。これは機能します:

em.find(entity.class, entitiy.getId())
em.detach(entity)
entity = em.merge(entity)  
4

2 に答える 2

2

マージによって返されたものではなく、古いエンティティ参照をまだ使用しているということですか?

マージ操作は、指定されたエンティティを再接続しません。マージ操作は、既に読み込まれているエンティティを探しますが、エンティティが見つからないため (デタッチしたため)、データベースからエンティティを読み込み、提供されたエンティティ データをデータベースから新しいコピーにコピーします。

次のようなことをすると:

MyEntity myEntity = em.find(MyEntity.class, myEntity.getId())
em.detach(myEntity);
em.merge(myEntity);

次に、 myEntity をマージ結果に再割り当てしないため、実際のマージされたエンティティを単に破棄します。代わりにこれを行う必要があります。

myEntity = em.merge(myEntity);

これで myEntity は、添付されたエンティティ (第 1 レベル キャッシュ、別名永続コンテキストに読み込まれたエンティティ) を参照します。

于 2014-11-10T12:09:00.890 に答える
1

申し訳ありませんが、私のせいで、断食しました。

ここを見てください、非常に良い説明です:

http://blog.xebia.com/2009/03/23/jpa-implementation-patterns-saving-detached-entities/

重要な文は次のとおりです。

つまり、EntityManager.merge を呼び出した後、渡された元のオブジェクトの代わりに、そのメソッドから返されたエンティティ参照を使用する必要があります。

したがって、手がかりは、マージ後もエンティティ オブジェクトは切り離されたままですが、マージからの結果のオブジェクト コピーが永続化コンテキストに再度接続されることです。

于 2014-11-10T12:07:26.673 に答える