-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 
Author Message
 Post subject: Auditing collection changes
PostPosted: Wed Mar 26, 2008 3:21 am 
Pro
Pro

Joined: Tue Jun 12, 2007 4:13 am
Posts: 209
Location: Berlin, Germany
Hello,

does anybody have an idea how to comfortably register any changes on a collection of an entity (additions and removals)? The normal interceptors only support changes of entity attributes.

Carlo


Top
 Profile  
 
 Post subject: Auditing collection changed?
PostPosted: Tue Apr 08, 2008 2:58 am 
Pro
Pro

Joined: Tue Jun 12, 2007 4:13 am
Posts: 209
Location: Berlin, Germany
Well, nobody answered so far, so it I try another way.

For my purposes of auditing changes in entities and their relations I implemented a JPA interceptor ("extends EmptyInterceptor") which does it's work onFlushDirty. Hibernate invokes it on an entity and gives it an Object[] currentState and an Object[]previousState.

This works nicely for non-collection values. But I also wanted to know if a collection changed: if an entry was added or removed.

The bad thing for collection values is: previousState doesn't give me the previous state! As I can see in the debuger, the method DefaultFlushEntityEventListener.invokeInterceptor does a call entry.getLoadedState() which should get the previous state. The sad thing for me, that the collections for current and previous state obviously are the same. So, at this point, I cannot tell if an object was added or removed from the collection.

Does anybody have an idea how, where and when I can get this information in the process of flushing?

Carlo


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 01, 2008 11:03 am 
Newbie

Joined: Sun May 08, 2005 12:26 pm
Posts: 10
Hi, are there any news concerning this question?
I ran into the same problem...

Regards
Burkhard


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 01, 2008 11:14 am 
Newbie

Joined: Sun May 08, 2005 12:26 pm
Posts: 10
Hi, are there any news concerning this question?
I ran into the same problem...

Regards
Burkhard


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 15, 2008 11:57 am 
Newbie

Joined: Mon Dec 15, 2008 11:33 am
Posts: 2
Hi,

I've been facing the same problem with onFlushDirty() since it doesn't report correctly when a collection property changes. I haven't seen a solution of that problem in the forum so that here it goes.

Looking at the hibernate source code I realized that entity and collection flushes are handled in a kind of independent fashion (not only flushes but also the representation of the objects) and onFlushDirty() is invoked only when an entity flush takes place.

The last couple days this issue really drove me nuts :( but finally I come to a solution, a bit trickier than that provided by onFlushDirty() that may require an extra work:

- In your interceptor, override onCollectionUpdate(), that method will be invoked when a collection is marked as dirty and must be updated.
- The first parameter of that method is likely to be an instance of PersistentCollection. It encapsulates a copy of the collection when the parent entity was attached (or loaded) into the session. So you must cast it to that type and invoke getStoredSnapshot() (this can be left out if you're not interested in the old value of the collection)
- If you want to know what property that collection maps to, it can be found out by invoking getRole(). You can also do getOwner() to obtain the parent entity that owns the collection.

Hope it works for you

Greetings,

Juan


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 15, 2008 1:46 pm 
Newbie

Joined: Mon Dec 15, 2008 11:33 am
Posts: 2
After a while performing some tests, I concluded that the technique described above is not reliable. Why not? Because of lazy associations.
For instance, I have a Country object that has a collection of State object. If I do:

country.getStates().clear()

on a populated collection, there are changes that must be flushed to the persistent medium. However, the old state (the StoredSnapshot) might be present depending on whether the collection was previously initialized or not. To complicate things even more, the value of such snapshot in that case is not null, but an empty ArrayList.

So, there will be cases in which we'll have the old state in memory and cases that we won't. In the latter that old state should be fetched from the database (that would imply a performance penalty, of course), presumably using another session/transaction.

Now, do you understand why onFlushDirty wasn't working for collections? :P


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.