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