Enabling ENABLE_LAZY_LOAD_NO_TRANS results in trying to remove elements in collections
Description
This worked fine in Hibernate-4.1.7 but stopped working in 4.1.8
Iterating over a collection in an Entity outside the transaction (persistence-context) makes org.hibernate.engine.internal.Collections.prepareCollectionForUpdate() think that ownerChanged == true, which results in:
// Collections:252 in Hibernate-4.1.9.Final entry.setDoremove( true );
This means that Hibernate will silently clear collections and remove data if you access a collection outside the transaction with ENABLE_LAZY_LOAD_NO_TRANS enabled.
As if this is not bad enough, if you have a constraint in the DB preventing this delete, then this results in Hibernate leaking connections because ( ( Session) session ).getTransaction().commit() in AbstractPersistentCollection:241 throws an Exception, resulting in the connection not being closed on line 243.
Attachments
2
19 Jun 2013, 04:24 PM
19 Jun 2013, 04:24 PM
Activity
Show:
Vojtěch Knyttl March 21, 2014 at 10:25 PM
Brilliant, thanks! How long does it take to have this in maven repository?
Steve Ebersole March 21, 2014 at 6:58 PM
Yeah the original test case was not very good in terms of using in the regression suite. It did not assert anything useful..
Aleksander Dukhno March 21, 2014 at 6:46 PM
<face-palm>My mistake is that I thought I should get some kind of Exception</face-palm> according to attached .java file. Thanks for clarification.
Steve Ebersole March 21, 2014 at 6:35 PM
Well that assert failure is the whole point of this bug report...
Aleksander Dukhno March 21, 2014 at 6:33 PM
I didn't get how you fixed my test case.
I removed
for ( Child c : children ) {
c.setParent( this );
}
Then do this
Parent p = new Parent();
for ( int i = 0; i < CHILDREN_SIZE; i++ ) {
Child c = new Child();
c.setParent( p );
}
s.persist( p );
List<Child> children = new ArrayList<Child>();
for ( int i = 0; i < CHILDREN_SIZE; i++ ) {
Child c = new Child();
s.persist( c );
lastChildID = c.getId();
children.add( c );
}
Parent p = new Parent();
p.setChildren( children );
s.persist( p );
This worked fine in Hibernate-4.1.7 but stopped working in 4.1.8
Iterating over a collection in an Entity outside the transaction (persistence-context) makes org.hibernate.engine.internal.Collections.prepareCollectionForUpdate() think that ownerChanged == true, which results in:
// Collections:252 in Hibernate-4.1.9.Final
entry.setDoremove( true );
This means that Hibernate will silently clear collections and remove data if you access a collection outside the transaction with ENABLE_LAZY_LOAD_NO_TRANS enabled.
As if this is not bad enough, if you have a constraint in the DB preventing this delete, then this results in Hibernate leaking connections because ( ( Session) session ).getTransaction().commit() in AbstractPersistentCollection:241 throws an Exception, resulting in the connection not being closed on line 243.