From: Dave S. (JIRA) <no...@at...> - 2006-06-22 14:36:37
|
[ http://opensource.atlassian.com/projects/hibernate/browse/HHH-1564?page=comments#action_23373 ] Dave Syer commented on HHH-1564: -------------------------------- I find that there is another spurious update of the parent object when it is first inserted (also causes the same potential constraint violation in the kind of trigger-driven situation originally outlined in this issue). Thus: Bar bar = new Bar(); // Bar is versioned Foo foo = new Foo(); bar.getFoos().add(foo); // bar.foos are cascaded session.save(bar); session.flush(); results in: INSERT INTO BAR ... INSERT INTO FOO ... UPDATE BAR ... The UPDATE operation increments the version number of bar, but nothing else changes. Hibernate only thinks that the Bar is dirty because its foos changed from a HashSet before the INSERT into a PersistentBag afterwards. The java docs for PesistentBag is quite explicit that it doesn't follow the Collection API convention of making an item by item comparison in equals(). If it did, then the UPDATE wouldn't happen because the Bar would not be dirty. Ironically, while the UPDATE is an issue for me because business users simply cannot see the logic in it, if it went away, an even bigger issue would be the fact the the INSERT statements come in the wrong order to make the audit trail show the Bar with the correct collection of Foos at the time it was created. The Foos are only properly present in version 1 of bar. But even worse, if the INSERTs happened the other way round, I might have a null constraint violation on inserting the Foo (it's parent Bar would not be persisted yet). Maybe that is wrong, or could be addressed in another way? > Possible bug with deleting versioned object (patch included) > ------------------------------------------------------------ > > Key: HHH-1564 > URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-1564 > Project: Hibernate3 > Type: Bug > Components: core > Versions: 3.1.2 > Environment: 3.1rc2 > Reporter: N Clayton > Attachments: onetomanydelete_test.tar.gz > > > We're seeing an odd problem when trying to delete a row. The code that does this simply creates a new object, commits it, starts a new session, finds the object, deletes it. It dies with a constraint violation on an audit table, because hibernate is issuing an unnecessary update operation (and not incrementing the version either). Further debugging shows that Hibernate thinks that three properties on the object are 'modified'. These three are collections. One is the points collection, one owners and the other is systems. Hibernate seems to think that they are 'different' because null != an empty collection. So, it thinks it needs to update the object. However; later on - it doesn't increment the version number - because it knows the object is to be deleted. Thus - a problem. > A complete description is here: > http://forum.hibernate.org/viewtopic.php?t=950225&highlight=collectiontype+isdirty > This appears to be fixed if we change CollectionType.isDirty() to be: > public boolean isDirty(Object old, Object current, boolean[] checkable, SessionImplementor session) > throws HibernateException { > if(checkable.length == 0) { > // Assume not checkable > return false; > } > return isDirty(old, current, session); > } -- This message is automatically generated by JIRA. - If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators.jspa - For more information on JIRA, see: http://www.atlassian.com/software/jira |