2017-01-17 17 views
2

JPAプロジェクトで予期しない動作が発生しました。分離されたエンティティのライフサイクルコールバックは、マージバック時に呼び出されません。

基本的に、私のエンティティは次のようにすべての更新時に呼び出され、そのmodified()方法があります。

@PrePersist 
@PreUpdate 
private void callback() { 
    modified(); // sets a java.util.time.Instant 
} 

正常に動作します。

ある時点で、エンティティを切り離して、変更してから元に戻しました。コールバックは呼び出されません。

これはバグか、文書化された仕様の一部ですか?

問題がある場合は、私はEclipseLinkを使用しています。


EDIT:完全に異なる問題に追跡しました。この問題はこの質問とは関係ありません。

+0

マージを含むすべての操作を行う場所でトランザクションメソッドをアタッチできますか? –

答えて

2

私はいくつかのテストを行いました。これは私が見つけたものであり、私の意見は(JPA 2.1を使用しています)です。

merge()操作は、まだ保持されていない新しいエンティティで呼び出されたときだけです。次に、persist()操作として動作し、@PrePersist注釈付きクラスが呼び出されます。

PrePersistPreRemoveコールバックメソッドがそのエンティティのそれぞれEntityManagerpersistremove 操作が実行される前に所与 エンティティに対して起動されている: これは仕様のような正しい動作です。 マージ操作が適用され、新たに 管理対象インスタンスが作成されるエンティティの場合、エンティティ状態がコピーされた後、管理対象インスタンス に対してPrePersistコールバックメソッドが呼び出されます。

ここでは、既存のエンティティを変更し、呼び出すことができるリスナーは@PreUpdate/@PostUpdateです。仕様のよう けれども、あなたが持っている:それは、エンティティが永続化と は、その後、単一のトランザクションで変更されたりする場合、エンティティが を変更されたときに更新前と PostUpdateコールバックが発生したかどうかが実装依存であることを

注意を単一のトランザクション内で削除されます。 ポータブルアプリケーションは、そのような動作に依存してはなりません。

私は、エンティティが変更され、その後削除されるというシナリオに従っていると思います。あなたのケースで取り外されたときには、PersistenceContextの意味が削除されました。この場合、その動作は予測できません。 いくつかのテストの後、私はこのような場合にリスナーメソッドが呼び出されないことを確認します。

どのような方法でもこの動作を実行できる追加設定が見つかりませんでした。 希望に役立ちます。

+0

私のPCの前でテストするのではなく、切り離し、変更、マージはすべて同じトランザクション内にある。 (思い出すことはできませんが、 'merge()'が 'TransactionAttribute.REQUIRES_NEW'のメソッドを介して呼び出されていると思います。) – Mordechai

+0

デタッチは変更前です。 – Mordechai

+0

私は言ったように、それはまた、他のユーザーがトランザクションコードを見て、特にその新しいトランザクションで起こっている一般的なケースではないことが有益だろう –

関連する問題