2009-05-01 42 views
3

在Hibernate中,實施PostUpdateEventListener允許你插入Hibernate的工作流程,讓您有機會檢查和比較實體屬性的新舊值,因爲它被保存(PostUpdateEvent有方法getOldState()getState()返回這些值的數組)。對於標準屬性,這工作得很好。但是,如果其中一個屬性是內容已更改的集合,則這沒有任何幫助:「舊值」和「新值」都與集合的引用相同(因爲集合本身沒有更改,只是其內容)。這意味着您只能看到該集合的最新內容,即「新」內容。如何確定Hibernate PostUpdateEventListener中的集合更改?

任何人都知道是否有方法可以確定工作流中此時實體擁有的集合的元素如何更改?

回答

6

我想出了一個辦法來做到這一點,所以我會張貼它的使用情況下,其他人。此代碼循環遍歷所有「舊狀態」屬性,對於任何持久集合,都會獲取以前的內容「快照」。然後它封裝此不可修改的Collection好措施在:

public void onPostUpdate(PostUpdateEvent event) 
{  
    for (Object item: event.getOldState()) 
    { 
     Object previousContents = null; 

     if (item != null && item instanceof PersistentCollection)    
     { 
     PersistentCollection pc = (PersistentCollection) item; 
     PersistenceContext context = session.getPersistenceContext();    
     CollectionEntry entry = context.getCollectionEntry(pc); 
     Object snapshot = entry.getSnapshot(); 

     if (snapshot == null) 
      continue; 

     if (pc instanceof List) 
     { 
      previousContents = Collections.unmodifiableList((List) snapshot); 
     }   
     else if (pc instanceof Map) 
     { 
      previousContents = Collections.unmodifiableMap((Map) snapshot); 
     } 
     else if (pc instanceof Set) 
     { 
      //Set snapshot is actually stored as a Map     
      Map snapshotMap = (Map) snapshot; 
      previousContents = Collections.unmodifiableSet(new HashSet(snapshotMap.values()));   
     } 
     else 
      previousContents = pc; 

     //Do something with previousContents here 
    } 
+0

你怎麼比較集合?我沒有看到'significantChange`方法足夠了。 – 2012-08-14 14:55:20

1

似乎有一個接口專門用於捕捉收集相關的改變。

Audit Log implementation Full

public void onPreUpdateCollection(PreCollectionUpdateEvent event) { 
    if (bypass(event.getAffectedOwnerOrNull().getClass())) { 
     return; 
    } 
    CollectionEntry collectionEntry = getCollectionEntry(event);  
} 


protected CollectionEntry getCollectionEntry(AbstractCollectionEvent event) { 
    return event.getSession().getPersistenceContext() 
      .getCollectionEntry(event.getCollection()); 
} 
相關問題