2012-06-21 89 views
17

我正在使用Spring 3.1.0.RELEASE,JSF 2.x,JPA 2和Hibernate Provider,MySql 5.1.x來完成一個Web應用程序。該應用程序在Tomcat 7.X上運行。觸發器與JPA事件

在我的實體,我有一些日子像上次更新日期:

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

目前我有一個觸發的更新:

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

它工作正常,但我注意到,有是JPA中的一些回調方法http://www.objectdb.com/java/jpa/persistence/event

JPA Events和MySql的觸發器之間的最佳方式是什麼?

謝謝。

回答

13

我已經用它與觸發器在數據庫中,並與JPA聽衆左右逢源,我已經在JPA聽衆定居,因爲:

  • 交談中JPA代碼數據庫中的唯一代碼,所以我不不必擔心時間戳記字段已經過時。 (如果這將在未來發生變化,我可以添加觸發器並更改映射的超級歸屬)

  • JPA偵聽器不那麼複雜,因爲我不必在數據庫中創建大量觸發器,所以我的東西較少保持。由於我正在積極地開發和更改數據庫結構,因爲我很快就不必去更新觸發器,因爲我正在快速迭代開發。

  • 我對數據庫的完全控制,並提出了每一個表是要有一個整數p鍵分貝,而一個完整版本的規則,並加時間戳表將有insert_tsupdate_ts列,這些都是普遍規則在我的數據庫設計,這樣的生活很容易我有這兩個映射superclases,使我的所有enitites簡單的代碼,因爲我從他們延伸。

@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事件唯一的問題是如果你想用SQL更新數據庫?這將繞過JPA事件。一般來說,數據庫應該是自治的,因此DBA會告訴你使用觸發器。開發人員更喜歡JPA事件。 –

18

有沒有最好的事。無論用於更新行(Hibernate,JDBC查詢或來自數據庫管理工具的更新)的方式,數據庫觸發器都會更新每行更新的最後更新日期。只有使用JPA更新行時,纔會調用JPA回調。你可能需要一個或另一個。

另一個區別是JPA不知道數據庫執行的觸發器。因此,如果更新實體中的某個字段,並且JPA刷新了更改,則更新日期將由觸發器修改,但JPA實體會將更新日期的舊值保留在內存中。因此,如果此更新日期在更新後顯示在GUI中,則更新日期將不正確。您必須刷新實體以獲取最新的更新日期。

+1

在第2段的評論是非常有用的。 –

+0

完美簡潔的數據庫觸發器和JPA回調方法之間的差異集。如果您的用例需要,cron作業也是一個很好的選擇。 – HopeKing