2009-12-09 28 views
7

StackOverflowで同様の質問がありましたが、解決策を試しましたが、答えが見つかりませんでした。EclipseLink JPA `@ PreUpdate`呼び出しが永続しない

私はかなり一般的なJPA戦略を使用して、一部のエンティティで最終変更時刻を設定しています。列とフィールドを設定し、メソッドを​​にタグ付けし、それらに現在の時刻を設定させます。

問題は、メソッドが呼び出され、フィールドが更新されていることをデバッガで確認できますが、DBログではUPDATEを含まない変更されたフィールドをUPDATEするSQLコールしか表示されませんタイムスタンプフィールド。

さらに複雑なものを@PrePersistは完全に動作しますが、​​のみがこの動作をします。

これまでに私が見つけた最も近い説明は、LINKです。で

同様の質問:#1725699および#1745890

私はのGlassFish v2の互換性のためのEclipseLink JPA v2とV1を使用しています。

私は両方の注釈をEntityクラスのメソッドで直接使用しようとしましたが、@EntityListener注釈を使用してEntityクラスに添付されたEntityListenerも試しました。

これはEclipseLinkのバグだと思われますが、私はそれを証明できません。

バグかどうか私はこの簡単な操作がうまくいくことを願っています。この実装に何か問題はありますか?これはEclipseLinkの既知の問題ですか?これはJPAの既知の問題ですか?これを回避する方法はありますか?

データベースにアクセスしてトリガーを使用するのは、Javaコードでupdated_onタイムスタンプを設定できる代替パスですか?

アドバイスをいただきありがとうございます。

コードスニペットが続きます。

エンティティフィールド:

@Column(name = "updated_on") 
@Temporal(TemporalType.TIMESTAMP) 
private Date updatedOn; 
@Column(name = "created_on") 
@Temporal(TemporalType.TIMESTAMP) 
private Date createdOn; 

注釈付きの更新方法:

@PreUpdate 
public void setUpdatedOn(Timestamped object) { 
    object.setUpdatedOn(new Date()); 
} 

@PrePersist 
public void setCreatedOn(Timestamped object) { 
    if (object.getCreatedOn()==null) { 
     object.setCreatedOn(new Date()); 
    } 
} 

答えて

4

あなたが提供するリンクが正確に自分の状況を説明します@PreUpdateメソッドが呼び出される前に、汚れのチェックのために、更新されたフィールドが検出され、 @PreUpdateメソッドの変更はこれ以上検出されません。ダーティチェックはラージオブジェクトグラフ上で非常に高価になる可能性があるため、これはおそらくパフォーマンス上の理由から行われます。今は、プロバイダー固有のメカニズム(DescriptorEvent)を使用するか、Hibernateに切り替えることが選択肢です。

+0

フェリックスに

<property name="eclipselink.temporal.mutable" value="true" /> 

を定義するのいずれか - 明確化をありがとうございました。私はそれが私が見ていたものだと思った。 DescriptorEventハンドリングの実装方法は、いくつかのメソッドに注釈を付けるのと同じくらい簡単です。適切なXMLファイルを見つけてハンドラを追加するだけです。 もう一度おねがいします! – Freiheit

+0

こんにちはFreiheit、私は今同じ問題に直面しています、DescriptorEventコードを例として共有してもらえますか? :)ありがとう – sunnycmf

+0

@Freiheitは解決策も見たいと思う。前もって感謝します。 –

3

Mybe少し遅れますが、情報の完全性のため、これはバグではありませんが、文書化行動:それは希望する場合

日やカレンダーの種類は、ませは、デフォルトでは変更可能であると想定されています日付またはカレンダーのsetメソッドを呼び出すには、マッピングを@Mutableに設定する必要があります。

日付とカレンダーのタイプでは、グローバル永続性プロパティ "eclipselink.temporal.mutable"を "true"に設定することもできます。

ので、

@Mutable 
@Column(name = "updated_on") 
@Temporal(TemporalType.TIMESTAMP) 
private Date updatedOn; 

に注釈を付けるか、persistence.xmlの

+0

ありがとうミシェル、それは私の魅力のような仕事です。 –

+0

あなたは大歓迎です:) –

+0

私はこの注釈を追加しましたが、まだ動作していません([私の質問を参照](https://stackoverflow.com/questions/47081932/prepersist-not-working-with-mappedsuperclass-in-hibernate -spring-environment))。どんな考え? – displayname

関連する問題