Skip to content

Commit 35b9a9d

Browse files
Shawn Clowaterbrmeyer
Shawn Clowater
authored andcommitted
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.
1 parent e7cb818 commit 35b9a9d

File tree

2 files changed

+71
-8
lines changed

2 files changed

+71
-8
lines changed

hibernate-core/src/main/java/org/hibernate/collection/internal/AbstractPersistentCollection.java

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -140,16 +140,22 @@ protected boolean readSize() {
140140
@Override
141141
public Boolean doWork() {
142142
CollectionEntry entry = session.getPersistenceContext().getCollectionEntry( AbstractPersistentCollection.this );
143-
CollectionPersister persister = entry.getLoadedPersister();
144-
if ( persister.isExtraLazy() ) {
145-
if ( hasQueuedOperations() ) {
146-
session.flush();
143+
144+
if ( entry != null ) {
145+
CollectionPersister persister = entry.getLoadedPersister();
146+
if ( persister.isExtraLazy() ) {
147+
if ( hasQueuedOperations() ) {
148+
session.flush();
149+
}
150+
cachedSize = persister.getSize( entry.getLoadedKey(), session );
151+
return true;
152+
}
153+
else {
154+
read();
147155
}
148-
cachedSize = persister.getSize( entry.getLoadedKey(), session );
149-
return true;
150156
}
151-
else {
152-
read();
157+
else{
158+
throwLazyInitializationExceptionIfNotConnected();
153159
}
154160
return false;
155161
}

hibernate-core/src/test/java/org/hibernate/test/legacy/FooBarTest.java

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@
4242
import java.util.TreeMap;
4343
import java.util.TreeSet;
4444

45+
import org.hibernate.action.spi.BeforeTransactionCompletionProcess;
46+
import org.hibernate.engine.spi.SessionImplementor;
47+
import org.hibernate.event.spi.EventSource;
48+
import org.hibernate.testing.*;
4549
import org.jboss.logging.Logger;
4650
import org.junit.Test;
4751

@@ -3935,6 +3939,59 @@ public void testLazyCollections() throws Exception {
39353939
s.close();
39363940
}
39373941

3942+
@Test
3943+
@TestForIssue(jiraKey = "HHH-7603")
3944+
public void testLazyCollectionsTouchedDuringPreCommit() throws Exception {
3945+
Session s = openSession();
3946+
s.beginTransaction();
3947+
Qux q = new Qux();
3948+
s.save( q );
3949+
s.getTransaction().commit();
3950+
s.close();
3951+
3952+
s = openSession();
3953+
s.beginTransaction();
3954+
q = ( Qux ) s.load( Qux.class, q.getKey() );
3955+
s.getTransaction().commit();
3956+
3957+
//clear the session
3958+
s.clear();
3959+
3960+
//now reload the proxy and delete it
3961+
s.beginTransaction();
3962+
3963+
final Qux qToDelete = ( Qux ) s.load( Qux.class, q.getKey() );
3964+
3965+
//register a pre commit process that will touch the collection and delete the entity
3966+
( ( EventSource ) s ).getActionQueue().registerProcess( new BeforeTransactionCompletionProcess() {
3967+
@Override
3968+
public void doBeforeTransactionCompletion(SessionImplementor session) {
3969+
qToDelete.getFums().size();
3970+
}
3971+
} );
3972+
3973+
s.delete( qToDelete );
3974+
boolean ok = false;
3975+
try {
3976+
s.getTransaction().commit();
3977+
}
3978+
catch (LazyInitializationException e) {
3979+
ok = true;
3980+
s.getTransaction().rollback();
3981+
}
3982+
finally {
3983+
s.close();
3984+
}
3985+
assertTrue( "lazy collection should have blown in the before trans completion", ok );
3986+
3987+
s = openSession();
3988+
s.beginTransaction();
3989+
q = ( Qux ) s.load( Qux.class, q.getKey() );
3990+
s.delete( q );
3991+
s.getTransaction().commit();
3992+
s.close();
3993+
}
3994+
39383995
@Test
39393996
public void testNewSessionLifecycle() throws Exception {
39403997
Session s = openSession();

0 commit comments

Comments
 (0)