2014-10-18 118 views
1

在onPostUpdateCollection事件收集舊值我使用Hibernate 4.2持久性存儲。我正在實現hibernate事件偵聽器以在特定對象被修改時獲取通知。 試過在hibernate中實現PostUpdateEventListener事件,但它在更新集合值時不會觸發方法。 目前正在實施PostCollectionUpdateEventListener,當收集更新時觸發方法。獲取休眠

類是如下

public class Employee { 
    private int id; 
    private String name; 
    private Set<Address> addresses; 

    //all getters and setters are implemented. 
} 

public class Address { 
    private int id; 
    private String street; 
    private String city; 

    //all getters and setters are implemented. 
} 

我已經實現測繪與所有的映射的xml文件,並以下一組映射

在Employee.hbm.xml

<hibernate-mapping> 
    <class name="Employee"> 
    ... all mappings 
    <set name="addresses" inverse="true" cascade="all-delete-orphan"> 
    <key column="Emp_id"/> 
    <one-to-many class="Address"/> 
    </set> 
</hibernate-mapping> 

地址。 hbm.xml文件正確實施。

在Hibernate事件偵聽器

public void onPostUpdateCollection(PostCollectionUpdateEvent event) { 
    Object obj = event.getAffectedOwnerOrNull(); 
    //this gives me updated values. 

    I want now code to get old collection values which going to be deleted. 
} 

我曾嘗試以下行

PersistentCollection collection = event.getCollection(); 
// this gives new update collection values of addresses 

我見過方法PersistentCollection Serializable getStoredSnapshot()但它給空值。

以任何方式,如果我能得到老的收藏價值,請您幫助我。 我插入新的地址值,以便觸發Employee類對象上的事件方法onPostUpdateCollection()

我的問題是: 我如何可以檢索收集的舊值? 試圖從兩天中獲得舊值,任何幫助將非常感激。 在此先感謝。

回答

3

在PostCollectionUpdateEventListener有沒有辦法讓老收藏價值。 我用PreCollectionUpdateEventListener類來獲得收舊值如下

public void onPreUpdateCollection(PreCollectionUpdateEvent event) { 
    PersistentCollection collection = event.getCollection(); 
    HashMap snapshot = (HashMap) collection.getStoredSnapshot(); 
    //set values are also stored as map values with same key and value as set value 
    Set<Map.Entry> set = snapshot.entrySet(); 
    //Now this set contains key value of old collection values before update 
} 
1

要獲得從PostCollectionUpdateEvent舊的對象,我們需要訪問CollectionUpdateAction類。

我使用Hibernate的版本是5.1.3.Final。首先,通過擴展PostCollectionUpdateEvent創建一個包含oldObj引用的新類。

package org.hibernate.event.spi; 

import org.hibernate.collection.spi.PersistentCollection; 
import org.hibernate.persister.collection.CollectionPersister; 

public class MyPostCollectionUpdateEvent extends PostCollectionUpdateEvent { 

    private static final long serialVersionUID = 1L; 
    private Object oldObj; 

    public MyPostCollectionUpdateEvent(Object oldObj, CollectionPersister collectionPersister, PersistentCollection collection, EventSource source) { 
     super(collectionPersister, collection, source); 
     this.oldObj = oldObj; 
    } 

    public Object getOldObj() { 
     return oldObj; 
    } 

    public void setOldObj(Object oldObj) { 
     this.oldObj = oldObj; 
    } 
} 

CollectionUpdateAction是最終的類,所以不能擴展它。爲了克服這個問題,在你的項目中創建一個包org.hibernate.action.internal,並將CollectionUpdateAction類從hibernate-orm中複製到你的項目中,然後編輯這個類,設置舊的對象引用。

public class CollectionUpdateAction extends CollectionAction { 

    private final boolean emptySnapshot; 
    private Object oldObject; 

    /** 
    * Constructs a CollectionUpdateAction 
    * 
    * @param collection The collection to update 
    * @param persister The collection persister 
    * @param id The collection key 
    * @param emptySnapshot Indicates if the snapshot is empty 
    * @param session The session 
    */ 
    public CollectionUpdateAction(
      final PersistentCollection collection, 
      final CollectionPersister persister, 
      final Serializable id, 
      final boolean emptySnapshot, 
      final SessionImplementor session) { 
     super(persister, collection, id, session); 
     this.emptySnapshot = emptySnapshot; 
    } 

    @Override 
    public void execute() throws HibernateException { 
     final Serializable id = getKey(); 
     final SessionImplementor session = getSession(); 
     final CollectionPersister persister = getPersister(); 
     final PersistentCollection collection = getCollection(); 
     final boolean affectedByFilters = persister.isAffectedByEnabledFilters(session); 

     preUpdate(); 
     this.oldObject = session.getPersistenceContext().getSnapshot(collection); 
    ... 
    ... 
    ... 
    } 


    private void postUpdate() { 
     final EventListenerGroup<PostCollectionUpdateEventListener> listenerGroup = listenerGroup(EventType.POST_COLLECTION_UPDATE); 
     if (listenerGroup.isEmpty()) { 
      return; 
     } 
     final MyPostCollectionUpdateEvent event = new MyPostCollectionUpdateEvent(
       oldObject, 
       getPersister(), 
       getCollection(), 
       eventSource() 
     ); 
     for (PostCollectionUpdateEventListener listener : listenerGroup.listeners()) { 
      listener.onPostUpdateCollection(event); 
     } 
    } 

} 

請確保您的類在類路徑中的優先級高於hibernate jar。然後,只有這種解決方案將工作,你可以得到舊的對象監聽器類參考,

public class DummyCollectionEventListener implements PostCollectionUpdateEventListener { 

    @Override 
    public void onPostUpdateCollection(PostCollectionUpdateEvent event) { 
     if (event instanceof MyPostCollectionUpdateEvent) { 

      Object oldObjects = ((MyPostCollectionUpdateEvent) event).getOldObj(); 
      PersistentCollection persistentCollection = event.getCollection(); 

      String role = persistentCollection.getRole(); 
      String propertyName = role.substring(role.lastIndexOf(".") + 1, role.length()); 
      System.out.println("property name : " + propertyName); 

      if (persistentCollection instanceof PersistentList && oldObjects instanceof List) { 
       System.out.println("Old Object List : " + ((List<?>) oldObjects)); 
      } else if (oldObjects instanceof Map<?, ?>) { 
       Map<?, ?> props = (Map<?, ?>) oldObjects; 
       if (persistentCollection instanceof PersistentMap) 
        System.out.println("Old Object Map : " + props); 
       else if (persistentCollection instanceof PersistentSet) 
        System.out.println("Old Object Set : " + props.keySet()); 
       else 
        System.out.println("Unknown Class type : " + persistentCollection.getClass()); 
      } else { 
       System.out.println("Unknown event"); 
      } 
     } 
    } 
}