diff --git a/hibernate-core/src/main/java/org/hibernate/collection/internal/AbstractPersistentCollection.java b/hibernate-core/src/main/java/org/hibernate/collection/internal/AbstractPersistentCollection.java index 80db62ed21..983f7929be 100644 --- a/hibernate-core/src/main/java/org/hibernate/collection/internal/AbstractPersistentCollection.java +++ b/hibernate-core/src/main/java/org/hibernate/collection/internal/AbstractPersistentCollection.java @@ -140,16 +140,22 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers @Override public Boolean doWork() { CollectionEntry entry = session.getPersistenceContext().getCollectionEntry( AbstractPersistentCollection.this ); - CollectionPersister persister = entry.getLoadedPersister(); - if ( persister.isExtraLazy() ) { - if ( hasQueuedOperations() ) { - session.flush(); + + if ( entry != null ) { + CollectionPersister persister = entry.getLoadedPersister(); + if ( persister.isExtraLazy() ) { + if ( hasQueuedOperations() ) { + session.flush(); + } + cachedSize = persister.getSize( entry.getLoadedKey(), session ); + return true; + } + else { + read(); } - cachedSize = persister.getSize( entry.getLoadedKey(), session ); - return true; } - else { - read(); + else{ + throwLazyInitializationExceptionIfNotConnected(); } return false; } diff --git a/hibernate-core/src/test/java/org/hibernate/test/legacy/FooBarTest.java b/hibernate-core/src/test/java/org/hibernate/test/legacy/FooBarTest.java index 9d6cb6c83c..a7826131f5 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/legacy/FooBarTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/legacy/FooBarTest.java @@ -42,6 +42,10 @@ import java.util.TimeZone; import java.util.TreeMap; import java.util.TreeSet; +import org.hibernate.action.spi.BeforeTransactionCompletionProcess; +import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.event.spi.EventSource; +import org.hibernate.testing.*; import org.jboss.logging.Logger; import org.junit.Test; @@ -3935,6 +3939,59 @@ public class FooBarTest extends LegacyTestCase { s.close(); } + @Test + @TestForIssue(jiraKey = "HHH-7603") + public void testLazyCollectionsTouchedDuringPreCommit() throws Exception { + Session s = openSession(); + s.beginTransaction(); + Qux q = new Qux(); + s.save( q ); + s.getTransaction().commit(); + s.close(); + + s = openSession(); + s.beginTransaction(); + q = ( Qux ) s.load( Qux.class, q.getKey() ); + s.getTransaction().commit(); + + //clear the session + s.clear(); + + //now reload the proxy and delete it + s.beginTransaction(); + + final Qux qToDelete = ( Qux ) s.load( Qux.class, q.getKey() ); + + //register a pre commit process that will touch the collection and delete the entity + ( ( EventSource ) s ).getActionQueue().registerProcess( new BeforeTransactionCompletionProcess() { + @Override + public void doBeforeTransactionCompletion(SessionImplementor session) { + qToDelete.getFums().size(); + } + } ); + + s.delete( qToDelete ); + boolean ok = false; + try { + s.getTransaction().commit(); + } + catch (LazyInitializationException e) { + ok = true; + s.getTransaction().rollback(); + } + finally { + s.close(); + } + assertTrue( "lazy collection should have blown in the before trans completion", ok ); + + s = openSession(); + s.beginTransaction(); + q = ( Qux ) s.load( Qux.class, q.getKey() ); + s.delete( q ); + s.getTransaction().commit(); + s.close(); + } + @Test public void testNewSessionLifecycle() throws Exception { Session s = openSession();