1

次のような一意の PK を持つエンティティを削除しようとしています: 80253

次のコード行を実行して、このエンティティを削除します。

myEntityType1 = getEntityManager().find(MyEntityType1.class, 80253);
getEntityManager().remove(myEntityType1);
getEntityManager().flush();

これらのコードは、データベースとそのすべてのカスケード オブジェクトから実際に行を適切に削除します。これについては非常に満足しています。同じ主キーを使用する同様のエンティティを作成する必要があるときに問題が発生します (これは正しく行われているはずです)。

MyEntityType2 myEntityType2 = new MyEntityType2 ();
myEntityType2.copyData(myEntityType1); //access the data from the other object
//and retrieves the id 80253. myEntityType2 now has 80253 as ID.
getEntitymanager().persist(myEntityType2);

ここで、一意の制約 SQL エラーが発生します。既に存在する ID を挿入しようとすると、変更が自動的にロールバックされます (古いエンティティは削除されません)。これは、トップリンクが古いエンティティのレコードを削除したことをロガーで確認した後に発生します。

これがどのように発生するのか、なぜ機能しないのか、誰かが知っていますか? 記録として、entityManager のマージ、クローズ、クリアを試みましたが、何も機能していないようです。

JPAは悪いキャッシングか何かをするかもしれないと私には思えます。誰かが私に良い答えをくれることを願っています!=)

更新:一意の ID 制約に関する問題はなくなりましたが、削除された同じ主キーを持つ新しいサブクラスを作成すると、次の例外が発生します。

Exception Description: Trying to invoke [setApprovedWhen] on the object [null].  The 
number of actual and formal parameters differs, or an unwrapping conversion has failed.
Internal Exception: java.lang.IllegalArgumentException: object is not an instance of 
declaring class

オブジェクトを別のサブクラスに変更できないように思えますか?

4

1 に答える 1

2

EDIT: トランザクションを明示的に開始してコミットしてみてください。

エンティティの削除は、次の例に示すように、EntityManager メソッド remove(Object entity) を呼び出すのと同じくらい簡単です。削除するエンティティは管理されている必要があります。つまり、現在の永続化コンテキストで以前に読み取られている必要があります。

entityManager.getTransaction().begin();
myEntityType1 = getEntityManager().find(MyEntityType1.class, 80253);
getEntityManager().remove(myEntityType1);
entityManager.getTransaction().commit(); 

トランザクションが完了するか、EntityManager メソッドの flush() を呼び出すと、エンティティは削除されます。コンテナ管理の永続コンテキストでは、トランザクション境界はコンテナによって制御されます。

于 2009-09-01T10:01:18.113 に答える