HHH-7603 Changed AbstractPersistentCollection so that it would behave in a similar manner as 4.1.6 when using the default lazy load behavior for collections. With the changes for HHH-7603 the AbstractPersistentCollection was throwing a NPE instead of a LIE in a very particular case.

Added test that simulates a use case from Hibernate Search 4.1.1 as far as I can tell.
This commit is contained in:
Shawn Clowater 2012-09-14 18:22:50 -06:00 committed by brmeyer
parent e7cb81857e
commit 35b9a9d785
2 changed files with 71 additions and 8 deletions

View File

@ -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;
}

View File

@ -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();