2012-10-15 57 views
1

發現的實體,我想執行的方法(compareEntities)要求這是目前在數據庫中,剛剛被保存在對象的實體。像這樣的事情在我的DAO,其中EM是EntityManager的:加載數據,避免在持久化上下文

public void save(MyObj myObj) { 
    MyObj previous = null; 
    MyObj current = null; 
    Integer id = myObj.getId();  
    if (id == null) { 
     // new 
     current = em.persist(myObj); 
    } else { 
     previous = em.find(MyObj.class, id); 
     // update 
     current = em.merge(myObj); 
    } 
    compareEntities (previous, current); 
} 

的問題是,作爲將被保存在實體來源於數據庫和我進行了一些關於它的變化,當我嘗試從數據庫中獲取數據(使用find方法)由於在持久性上下文中找到了實體,因此我獲取了包含更改的數據。如果沒有我對同一事務中的實體所做的更改,是否有任何方法可以獲取數據庫中的數據?

謝謝。

+0

看起來像將整個邏輯移動到db會更好。 –

回答

1

有發現使用具有當前連接的是同一個實體的修改實例的持久化上下文的實體不變,沒有可靠的方法。持久性提供者可能已經刷新了對數據庫的更改,在這種情況下,後續SELECT將顯示改變對象,因爲這是在交易的電流。即使持久性提供尚未刷新的變化需要通過規範find調用返回同一個實例對於同一個密鑰。不允許返回「不變」的對象。

您將需要使用另一個連接,從一個新的事務獲取數據。如何做到這一點取決於你的編程模型。在使用容器管理的事務(如EJB3)的JTA編程模型中,您將使用@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)帶註釋的業務方法。在簡單的JPA中,您將獲得一個新的EntityManager,並通過ID獲取對象。

我懷疑你正在試圖實現一個審計日誌系統,在這種情況下,你應該看看Hibernate Envers,PostgreSQL audit trigger example或標準的JPA實體監聽器,所有這些都提供了更好的方法來實現這個任務。嘗試解釋你想要解決的根本問題,這個問題的「爲什麼」是「如何」。