-->
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.  [ 1 post ] 
Author Message
 Post subject: Interceptor onFlushDirty and Collections - detecting changes
PostPosted: Wed Jul 19, 2006 4:09 am 
Newbie

Joined: Wed Jul 19, 2006 2:54 am
Posts: 1
Location: Brisbane
Hi, Can someone help me by giving a little insight into the use of hibernate Interceptors?
I using them to notify a number of downstream systems about changes to persisted entities.

Doing this via Hibernate Interceptor by extending EmptyInterceptor, and (nearly) all is working well. There seems to be a problem if the item that has changed is a Collection; the previousState Object array seems to hold a pointer to the same Collection as the currentState Object array - so - as I check the properties of my entity for changes, I cannot detect that the previous collection is different from the current collection, because the values handed to my onFlushDirty implementation are the same object.

From the EmptyInterceptor signature -

public boolean onFlushDirty(Object entity,
Serializable id,
Object[] currentState,
Object[] previousState,
String[] propertyNames,
Type[] types)

I was expecting to be able to deduce what properties had changed (from previousState), however, if one of those properties is a Set, (for example), I can't seem to.

In my case I have a Group object, with properties of Sets that are parents or children (also of Group objects). When a parent is added, I need to notify other systems of the change.


Mapping documents:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="au.com.resolute.mongoose.model.Group" table="groups">
<id name="id" column="id" unsaved-value="null">
<!-- The generator-class attribute of @hibernate.id is deprecated, use the @hibernate.generator tag instead -->
<generator class="native">
</generator>
</id>
<version name="version" column="version"
type="java.lang.Integer" />
<set name="contactDetails" lazy="false" inverse="true"
cascade="all-delete-orphan">
<!-- @hibernate.collection-key tag is deprecated, use @hibernate.key instead -->
<key column="group_id">
</key>
<!-- @hibernate.collection-one-to-many tag is deprecated, use @hibernate.one-to-many instead -->
<one-to-many
class="au.com.resolute.mongoose.model.ContactDetail" />
</set>
<property name="creationDate" column="creation_date">
</property>
<property name="expiryDate" column="expiry_date">
</property>
<property name="name" length="100" not-null="true"
unique="false">
</property>
<set name="parentGroups" table="groups_groups" lazy="true"
cascade="save-update">
<!-- @hibernate.collection-key tag is deprecated, use @hibernate.key instead -->
<key column="parent_group_id">
</key>
<!-- @hibernate.collection-many-to-many tag is deprecated, use @hibernate.many-to-many instead -->
<many-to-many class="au.com.resolute.mongoose.model.Group"
column="sub_group_id" outer-join="auto" />
</set>
<set name="subGroups" table="groups_groups" lazy="true"
cascade="save-update">
<!-- @hibernate.collection-key tag is deprecated, use @hibernate.key instead -->
<key column="sub_group_id">
</key>
<!-- @hibernate.collection-many-to-many tag is deprecated, use @hibernate.many-to-many instead -->
<many-to-many class="au.com.resolute.mongoose.model.Group"
column="parent_group_id" outer-join="auto" />
</set>
<property name="permanent" type="yes_no"
column="is_permanent">
</property>
</class>
</hibernate-mapping>

TESTCASE:

Testcase method (from Appfuse standard extends BaseTestCase and AbstractTransactionalDataSourceSpringContextTests ):
public void testCRUD() {
// By Calling this super setComplete() method it actually commits the
// transaction
setComplete();
Group group;
// retrieve
group = (Group) dao.getObject(Group.class, new Long(42l));
Set priorParents = new HashSet<Group>(group.getParentGroups());

// update
group.addParentGroup((Group) dao.getObject(Group.class, new Long(44l)));
Set postParents = group.getParentGroups();

dao.saveObject(group);
assertEquals(priorParents.size(), postParents.size()-1);

}

And my interceptor gets called correctly, but the previous and current value for property[5] in the array (parentGroup) are the same object (Set) when onFlushDirty is getting called:

Debug scrape from entry point of onFlushDirty:
<<<< indicate worrisome object ID - that have changed but I can't tell how now as they are the same Set:

this TentacleUpdateHibernateInterceptor (id=40)
entity Group (id=46)
id Long (id=51)
value 42
currentState Object[8] (id=57)
[0] Integer (id=83)
[1] PersistentSet (id=69)
[2] Timestamp (id=81)
[3] null
[4] "Gladstone City Council"
[5] PersistentSet (id=82) <<<<<<<<<<<<<<<
[6] PersistentSet (id=88)
[7] Boolean (id=93)
previousState Object[8] (id=59)
[0] Integer (id=83)
[1] PersistentSet (id=69)
[2] Timestamp (id=76)
[3] null
[4] "Gladstone City Council"
[5] PersistentSet (id=82) <<<<<<<<<<<<<<<
[6] PersistentSet (id=88)
[7] Boolean (id=91)
propertyNames String[8] (id=62)
types Type[8] (id=65)

Tested with Hibernate version: 3.1 and 3.2cr2

Database & Driver:

Microsoft SQL Server 8.00.2039
Microsoft SQL Server 2005 JDBC Driver 1.0.809.102

Many Thanks for any assistance!

Regards,
Chris


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

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.