2012-06-21 5 views
17

私はSpring 3.1.0.RELEASE、JSF 2.x、JPA 2 with Hibernate Provider、MySql 5.1.xを使ってWebアプリケーションをやっています。アプリケーションはTomcat 7.X上で動作します。私のエンティティでトリガー対JPAイベント

私は最終更新日のようないくつかの日付があります。

CREATE TRIGGER upd_site BEFORE UPDATE ON site 
FOR EACH ROW SET NEW.last_update_date = CURRENT_TIMESTAMP(); 

をそれが正常に動作しますが、私はちょうどそれが気付か:瞬間のために

@Column(name = "last_update_date", insertable = false, updatable = false) 
@Temporal(TemporalType.TIMESTAMP) 
private Date lastUpdateDate; 

を私は更新トリガーを持っていますJPAのいくつかのコールバックメソッドですhttp://www.objectdb.com/java/jpa/persistence/event

JPAイベントとMySqlのトリガーの間のベストは何ですか?

ありがとうございました。

答えて

13

ので、私はそれをDB内のトリガーとし、JPAリスナーとの両方の方法を使用している、私はJPAリスナーに落ち着いてきた:JPAコードでデータベースに話し

  • コードのみので、私は「ドン時間切れになっているタイムスタンプフィールドについて心配する必要がありません。 (これが将来変更される場合は、トリガーを追加してマップされたスーパーカルを変更することができます)

  • JPAリスナーは、データベースに多くのトリガーを作成する必要がなくなるため、維持する。 DB構造を積極的に開発して変更しているので、開発をすばやく繰り返すうちにトリガーを更新したり更新したりする必要がないという偉大な道を歩みます。

  • 私はデータベースを完全に制御しており、すべてのテーブルが整数pkeyと整数バージョンを持つdbのルールを作成しました。タイムスタンプ付きテーブルはinsert_tsupdate_tsの列を持ちます私のdbデザインのルールは人生が簡単なので、私はこれらの2つのマップされたスーパークラスを持っています。

@MappedSuperclass 
public abstract class PersistableObject { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Column(name="pkey") 
    private Integer pkey; 

    @Version 
    @Column(name="version") 
    private Integer version; 

    public Integer getPkey() { 
     return this.pkey; 
    } 

    public Integer getVersion() { 
     return this.version; 
    } 

    @Override 
    public String toString() { 
     return "Presistable Object: pkey=" + this.pkey + " Object: " + this.getClass().getName(); 
    } 
} 

@MappedSuperclass 
public class TimeStampedPersistableObject extends PersistableObject { 

    @Column(name = "insert_ts") 
    @Temporal(TemporalType.TIMESTAMP) 
    private Date insertTimestamp; 

    @Column(name = "update_ts") 
    @Temporal(TemporalType.TIMESTAMP) 
    private Date updateTimestamp; 

    @SuppressWarnings("unused") 
    @PrePersist 
    private void onInsert() { 
     this.insertTimestamp = new Date(); 
     this.updateTimestamp = this.insertTimestamp; 
    } 

    @SuppressWarnings("unused") 
    @PreUpdate 
    private void onUpdate() { 
     this.updateTimestamp = new Date(); 
    } 


    public Date getInsertTimestamp() { 
     return this.insertTimestamp; 
    } 


    public Date getUpdateTimestamp() { 
     return this.updateTimestamp; 
    } 
} 
+3

JPAイベントの唯一の問題は、dbをSQLで更新したい場合です。 JPAイベントをバイパスします。一般にDBは自律型である必要があります。したがって、DBAはトリガーの使用を指示します。開発者はJPAイベントを好むでしょう。 –

18

最高ものはありません。データベース・トリガーは、行の更新に使用された方法(Hibernate、JDBC照会、またはデータベース管理ツールからの更新)に関係なく、行の更新ごとに最終更新日を更新します。 JPAコールバックは、JPAを使用して行が更新されたときにのみ呼び出されます。どちらか一方が必要な場合があります。

別の違いは、JPAがデータベースによって実行されるトリガーを認識していないことです。したがって、エンティティの一部のフィールドを更新し、JPAが変更をフラッシュした場合、更新日はトリガーによって変更されますが、JPAエンティティは更新日の古い値をメモリに保持します。したがって、この更新日が更新後にGUIに表示される場合、更新日は間違っています。エンティティを更新して最新の更新日を取得する必要があります。

+1

2番目の段落内のコメントは非常に便利です。 –

+0

データベース・トリガーとJPAコールバック・メソッドの違いを完全に簡潔にまとめたものです。あなたのユースケースがそうする必要があるなら、cronジョブも良い選択肢です。 – HopeKing

関連する問題