Edit 5/11/2011:
I guess it's a bit worse than what's below; in my deployed QA instance, if I just refresh the main dashboard a number of times, eventually my user's many-to-many group associations are deleted. At this point, there are only select statements being called on the server side; hopefully I'm getting it narrowed down with these latest tests.
Original:
Hi all. I'm having a problem with a rather complex object; problem is as follows: when I send the object from the client to server to be saved, it is seemingly randomly wiping out many-to-many relationships on associated objects. Worse yet, I am not able to reproduce the problem myself, after roughly two months of being aware of the problem. I have the app out for testing with a QA group; they're using the program daily, double entering in the new and legacy applications. The problem crops up as much as three times a day.
I'll do my best to provide as much detail as I can, and greatly appreciate anyone taking a look!
The app framework is GWT 2.1 + Gilead + Hibernate 3 + MySQL InnoDB. I'm letting Hibernate handle any cascading etc, so none is defined in the DB, although all foreign keys are set in the DB.
Here's some excerpts from the mappings:
<hibernate-mapping>
<class name="com.example.domain.Close" table="CLOSE">
<many-to-one name="updateUser"
class="com.example.domain.User"
column="LAST_UPDATE_USER"/>
</class>
</hibernate-mapping>
<hibernate-mapping>
<class name="com.example.domain.User" table="USER" batch-size="25">
<set name="groups" table="USER_GROUP" lazy="true" batch-size="25">
<key column="USER_ID"/>
<many-to-many column="GROUP_ID" class="com.example.domain.Group"/>
</set>
</class>
</hibernate-mapping>
<hibernate-mapping>
<class name="com.example.domain.Group"
table="GROUP" batch-size="25">
<set name="users" table="USER_GROUP" lazy="true" inverse="true">
<key column="GROUP_ID"/>
<many-to-many column="USER_ID" class="com.example.domain.User"/>
</set>
<set name="permissions" table="PERMISSION_GROUP" lazy="true" inverse="true">
<key column="GROUP_ID"/>
<many-to-many column="PERMISSION_ID"
class="com.example.domain.Permission"/>
</set>
<hibernate-mapping>
<class name="com.example.domain.Permission"
table="PERMISSION">
<set name="groups" table="PERMISSION_GROUP" lazy="true">
<key column="PERMISSION_ID"/>
<many-to-many column="GROUP_ID"
class="com.example.domain.Group"/>
</set>
</class>
</hibernate-mapping>
Saving the object is simple a call to saveOrUpdate():
Session session = gileadHibernateUtil.getSessionFactory()
.getCurrentSession();
session.beginTransaction();
try {
session.saveOrUpdate(close);
} catch (Exception e) {
e.printStackTrace();
session.getTransaction.rollback();
}
session.getTransaction.commit();
return close;
The Close 'updateUser' is an object loaded when the user logs in. It is loaded with the associated groups and permissions so the system can grant/deny access to app modules. I do
close.setUpdateUser(exampleApp.getUser());
before sending the object back to the server.
There are plenty of other places in the app where this sort of operation happens, but doesn't cause the unwanted side-effects. It probably boils down to the complexity of the client-side code associated with the Close object, or rather, my implementation of it.
I've spent so much time pouring over the official Hibernate docs, looking for possibly related problems, etc, I thought maybe it was a good time to ask for help. I have to man up and keep at it, but maybe just asking will help me figure it out.
I'm not sure what else to provide right now that's relevant. Hopefully what is here so far has relevance!
Thanks for listening!
Edit
May 5 12:18:38 localhost jsvc.exec[10117]: Hibernate: insert into example_dev.RECENT_ITEM (OBJECT_TYPE, OBJECT_ID, DATE, USER_ID) values (?, ?, ?, ?)
May 5 12:18:38 localhost jsvc.exec[10117]: Hibernate: delete from example_dev.PERMISSION_GROUP where PERMISSION_ID=?
May 5 12:18:38 localhost last message repeated 19 times
May 5 12:18:38 localhost jsvc.exec[10117]: Hibernate: delete from example_dev.USER_GROUP where USER_ID=?
May 5 12:18:38 localhost jsvc.exec[10117]: Hibernate: delete from example_dev.USER_DESIGNATION where USER_ID=?
It appears that deletes are happening right after this insert.. previous operations are all selects. But nothing in User should be cascading from RecentItem.