2012-04-12 32 views
0

我有兩個審計實體A和B.實體A擁有實體B的集合(註釋爲一對多關係)。當向數據庫中插入一個新的A實例時,A和B的所有行都處於相同的修訂版本(假設版本1)。然後,A上的更新隻影響實體B的實例。因此,在更新之後,實體A仍處於修訂版本1,而B的實體處於修訂版本2(包括審計表中的MOD條目) 。在修訂版3中,實體A被刪除。由於實體B的集合由@Cascade註釋,因此屬於A的實體B也被刪除。Hibernate Envers:使用集合屬性檢索實體的正確修訂

鑑於此場景,如何使用Envers創建一個審計查詢,獲取具有修訂版本2的更新實體B的實體A的實例?當我查詢實體A的所有修訂版本時,我要麼獲得不包含B實體(修訂版本3)的A的已刪除實體,要麼獲得包含修訂版本1的B實體的修訂版本1的A。

使用Hibernate 3.6,如果有幫助。

+0

涉及到http://計算器。 com/questions/10697945/hibernate-envers-track-revisions-the-owned-on-a-onetomany-relation和http://stackoverflow.com/questions/10529982/how-to-retrieve-the-審計修訂的關係 – Jean 2012-06-28 12:04:36

回答

2

如果您閱讀修訂版2中的實體A,您將獲得正確的數據。

目前沒有辦法獲得實體或相關實體更改的修訂列表(因爲您的情況 - 第2修訂版僅在B中更改,而不是在a中)。

+0

我已經嘗試在修訂版2中獲取A,但隨後審計查詢的結果列表爲空。我認爲這種行爲是正確的,因爲當然,在審覈表中沒有A的修訂2。 – 2012-04-12 14:55:10

+1

嗯,不,這很奇怪,在修訂2實體A存在。 啊!也許你正在使用錯誤的查詢。一個是找到在給定版本修改的實體(所以在rev2A沒有修改),另一個是找到實體,因爲它們存在於給定的rev(然後A存在於rev2)。 – adamw 2012-04-13 15:31:37

+1

謝謝,就是這樣。使用forEntitiesAtRevision()而不是forRevisionsOfEntity()解決了我的問題。 – 2012-04-24 14:55:37

0

在Hibernate中,我們可以通過指定懶惰來控制兒童的加載。因此,您需要在休眠配置中將以下行添加到您的類定義中,以便在讀/寫情況下加載所有關聯。

<cache usage="read-write"/> 

如果標記CacheMode.REFRESH那麼將寫數據到第二級緩存。不要從二級緩存讀取。

如果你在加載父母的時候沒有問題,你可以轉懶惰的,這將返回更新的信息。

+0

你不明白我的問題,是嗎? – 2012-04-12 10:54:12

+0

我試圖從問題中理解,但是如果你認爲我相反了解它,那麼請你儘可能簡短地表達它。 – Phani 2012-04-12 11:18:02

1

我通過在您的A實體的等價物上添加隱藏的lastUpdated日期字段來解決類似的問題。

@Entity 
public class A { 
    private Date lastModified; 
    @OneToMany(mappedBy = "a", cascade = CascadeType.ALL) 
    private List<B> blist; 
    public void touch(){ 
     lastModified=new Date(); 
    } 
} 

然後在相關實體(如你B場),我增加了以下內容:

public class B { 
    @ManyToOne 
    private A a; 

    @PreUpdate 
    public void ensureParentUpdated(){ 
     if(a!=null){ 
      a.touch(); 
     } 
    } 
} 

這確保了修訂版將添加到一個無論何時添加了修訂,即使過b需要許多實體的自定義代碼。

在你的情況,這將確保A的歷史實際上包含B的修訂這種方式,你只需要一個查詢來獲取整個A的所有修訂,燒烤圖形

相關問題