In Hibernate, implementing a PostUpdateEventListener allows you to plug into Hibernate's workflow and gives you the opportunity to inspect and compare the old and new values of an Entity's properties as it is being saved (PostUpdateEvent has methods getOldState() and getState() that return an array of these values). For standard properties, this works just fine. However, where one of those properties is a Collection whose contents have changed, this is of no help: the "old value" and "new value" are both just the same reference to the Collection (since the Collection itself has not changed, just its contents). This means you can only see the latest i.e. "new" contents of that Collection.
Anyone know if there is a way to determine how the elements of a Collection owned by an Entity have changed at this point in the workflow?
I figured out a way to do this, so I'll post it in case its of use to anyone else. This code loops through all the "old state" properties, and for any which are persistent collections, obtains the previous contents 'snapshot'. It then wraps this in an unmodifiable collection for good measure:
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
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With