2014-10-18 116 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"); 
      } 
     } 
    } 
}