2010-09-20 49 views
5

我們對項目有要求,我們需要維護對應用程序中的某些實體所做的某種更改歷史記錄。該應用程序是基於Struts,Spring和Hibernate的Java Web App。在這種情況下使用了什麼樣的方法?在Java Web應用程序中記錄實體更改

  • 觸發器在各自的表是一個想法,但他們不容易維護?也許他們也不應該成爲事務的一部分(如果觸發器失敗,那麼它就可以,但實體更新事務不應該失敗)。
  • 爲此,使用AoP是一個橫切關注點,但必須非常細化,因爲只有在實體更改時才捕獲值。 (所有編輯沒有相應的不同方法......很多編輯發生在單個Java方法中)。
  • 使用Hibernate Event Listeners。

有沒有其他方法可以做這種活動?

回答

3

因爲你說

所有編輯不具有其相應的不同的方法...... 許多編輯在一個單一的Java方法發生

即使你的方法只是獲得一個參數作爲參數,你可以檢索它的關係,AOP仍然是一個不錯的主意。我強烈建議你看這個nice article

Hibernate文檔本身說:

Hibernate的攔截器允許應用程序檢查和/或它被保存,更新,刪除或是加載之前操縱持久化對象的屬性。 一個可能的用途是跟蹤審計信息。

但它也說

確保你沒有保存sessionspecific狀態,因爲如果你使用Spring管理事務的多個會話使用這個攔截潛在的同時

,您可以通過使用sessionFactory.getCurrentSession();來獲取會話到當前的線程。

public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames, Type[] types) { 
    if(entity instanceof SomeEntity) { 
     Session session = sessionFactory.getCurrentSession(); 

getCurrentSession()文檔

如果沒有,你應該創建一個本地的Hibernate攔截器(連接在打開的會話),而不是一個全球性的攔截器(連接到SessionFactory的),然後,建立了會議

AuditableInterceptor interceptor = new AuditableInterceptor() 
Session session = sessionFactory.openSession(interceptor); 

/** 
    * do it before processing anything if you use local interceptor 
    */ 
interceptor.setSession(session); 

有關觸發器,它依賴於像數據庫管理等問題(你有DB管理權限。如果沒有,請與DBA是您最好的選擇)。

+0

感謝您的信息亞瑟。對於簡單的實現,我試圖擴展Hibernate Event Listener。 – 2010-09-20 10:29:46

+0

+1,用於通用解釋。 – Bozho 2010-09-20 14:43:38

+0

+1 as bozho said – 2010-09-23 01:58:04

4

JBoss Envers支持試聽和版本控制 - 請看一看。

+0

有意思(+1)你成功使用它了嗎? – 2010-09-20 14:13:15

+0

@Arhtur - 不,唉。但我知道使用它的人說它很好:) – Bozho 2010-09-20 14:16:02

+0

和+1也是。 Envers在這裏似乎很適合。 – 2010-09-23 01:58:31

相關問題