2014-02-12 47 views
2

形勢Java的JPA:如何檢查如果一個實體不同步(或「髒」)或變更的通知,以髒狀態

我有一個使用JPA爲紐帶,以Web應用程序底層數據庫。當用戶通過UI修改實體時,這些更改不會立即保存到數據庫中。

問題

如何檢查如果一個實體和底層數據庫不同步的(即,實體是)。

此外,是否有可能自動通知這種情況,例如,通過偵聽器機制?

這可能使用JPA規範嗎?我目前使用Hibernate作爲基礎持久性管理器,但JPA(EntityManager)中的解決方案會更好。

如果無法使用JPA,那麼也歡迎使用Hibernate 4持久性API的解決方案!

目的

我想用這個來標記髒對象是髒的UI表示。

加長版

在加載Web UI中,實體從數據庫加載。這些實體可能會在用戶界面中被用戶修改。但是,這些更改不會立即保存到數據庫中。

爲此,用戶必須按下保存按鈕,其持久性模塊中執行以下代碼:

// in data-persistency module 
public class MyObjectManager { 
    ... 
    public void saveMyObject(MyObjectEntity moe) { 
     ... 
     EntityManager em = DatabaseJPAConnector.getEntityManager(); 
     em.getTransaction().begin(); 
     moe.saveOrUpdate(em); // persists or merges moe and all its childs 
     em.getTransaction().commit(); 
     ... 
    } 
    ... 
} 

爲了測試對象是否是不同步的,我想驗證一個方法實體是目前骯髒和/或在髒的狀態改變的事件機制自動通知相關的GUI元素:

// in data-persistency module 
public class MyObjectManager { 
    ... 
    public boolean isDirty(MyObjectEntity moe) { 
     ... 
     EntityManager em = DatabaseJPAConnector.getEntityManager(); 
     return ??? 
    } 
    ... 
    public void addDirtyListener(DirtyStateListener listener) { 
     // publisher-subscriber pattern 
    } 
} 

// in gui module 
public class MyGUIComponent { 
    if (data.isDirty(moe)) { 
     // mark UI object as dirty 
    } 

    MyGUIComponent() { 
     data.addDirtyListener(new DirtyStateListener() { 
      public void dirtyStateChanged(DirtyStateEvent event) { 
       // update dirtyness state of UI object 
      } 
     } 
    } 
} 

回答

1

你可以使用實體監聽器(見JPA 2.1規範的3.5章)。在@PostUpdate@PostRemove方法你可以發起一個CDI事件 - 見3.5.1節。但這種方法有它的侷限性...

Entity listener classes in Java EE environments support dependency injection through the 
Contexts and Dependency Injection API (CDI) [ 10 ] when the containing archive is a bean 
archive. 

其他的解決辦法是使用樂觀鎖定和@Version屬性。這是更簡單的解決方案,即使在JPA 1.0中也可以工作。這是我選擇的解決方案。