Java 在hibernate的onPostUpdateCollection事件中获取集合中的旧值

Java 在hibernate的onPostUpdateCollection事件中获取集合中的旧值,java,hibernate,Java,Hibernate,我正在使用Hibernate4.2进行持久存储。我正在实现hibernate事件侦听器,以便在修改特定对象时获得通知。 尝试在hibernate中实现PostUpdateEventListener事件,但在更新集合值时不会触发方法。 当前正在实现PostCollectionUpdateEventListener,它在更新集合时触发方法 课程安排如下 public class Employee { private int id; private String name; private

我正在使用Hibernate4.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.
}
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
}
我试过下面这句话

PersistentCollection collection = event.getCollection();
// this gives new update collection values of addresses
我在PersistentCollection
Serializable getStoredSnapshot()
中看到了方法,但它给出了空值

无论如何,如果我能得到旧的集合值,请帮助我。 我正在插入地址的新值,以便它触发Employee类对象上的事件方法

我的问题是: 如何检索集合的旧值? 试图从几天内得到旧的价值观,任何帮助都将不胜感激。
提前感谢。

在PostCollectionUpdateEventListener中,无法获取旧集合值。 我使用PreCollectionUpdateEventListener类获取旧集合值,如下所示

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.
}
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
}
public void onPreUpdateCollection(PreCollectionUpdateEvent事件){
PersistentCollection=event.getCollection();
HashMap快照=(HashMap)集合。getStoredSnapshot();
//设定值也存储为与设定值具有相同键和值的映射值
Set=snapshot.entrySet();
//现在,此集合包含更新前旧集合值的键值
}

要从
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
,并将该类从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 );
        }
    }

}
公共类CollectionUpdateAction扩展CollectionAction{
私有最终布尔空快照;
私人客体;
/**
*构造一个CollectionUpdateAction
*
*@param collection要更新的集合
*@param persister集合persister
*@param id收集密钥
*@param emptySnapshot表示快照是否为空
*@param session在会话中
*/
公共集合更新操作(
最终PersistentCollection集合,
最终收集持久器持久器,
最终可序列化id,
最终布尔空快照,
最后一次会议(最后一次会议){
超级(持久器、集合、id、会话);
this.emptySnapshot=emptySnapshot;
}
@凌驾
public void execute()引发HibernateeException{
最终可序列化id=getKey();
最终会话Implementor会话=getSession();
最终集合persister persister=getPersister();
最终PersistentCollection=getCollection();
final boolean affectedByFilters=persister.isAffectedByEnabledFilters(会话);
预更新();
this.oldObject=session.getPersistenceContext().getSnapshot(集合);
...
...
...
}
私人无效假设更新(){
最终EventListenerGroup listenerGroup=listenerGroup(EventType.POST\u COLLECTION\u UPDATE);
if(listenerGroup.isEmpty()){
返回;
}
最终MyPostCollectionUpdateEvent事件=新建MyPostCollectionUpdateEvent(
oldObject,
getPersister(),
getCollection(),
eventSource()
);
对于(PostCollectionUpdateEventListener侦听器:listenerGroup.listeners()){
onpositionpdatecollection(事件);
}
}
}
确保在类路径中,类的优先级高于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");
            }
        }
    }
}
公共类DummCollectionEventListener实现了PostCollectionUpdateEventListener{
@凌驾
public void onPostUpdateCollection(PostCollectionUpdateEvent事件){
if(MyPostCollectionUpdateEvent的事件实例){
对象oldObjects=((MyPostCollectionUpdateEvent)事件);
PersistentCollection PersistentCollection=event.getCollection();
String role=persistentCollection.getRole();
String propertyName=role.substring(role.lastIndexOf(“.”+1,role.length());
System.out.println(“属性名称:“+propertyName”);
if(persistentCollection instanceof PersistentList&&oldObjects instanceof List){
System.out.println(“旧对象列表:”+((列表)旧对象));
}else if(地图的oldObjects实例){
地图道具=(地图)旧对象;
if(PersistentMap的persistentCollection实例)
System.out.println(“旧对象映射:+道具”);
else if(PersistentSet的persistentCollection实例)
System.out.println(“旧对象集:+props.keySet());
其他的
System.out.println(“未知类类型:+persistentCollection.getClass());
}否则{
System.out.println(“未知事件”);
}
}
}
}