HHH-17953 fix StatelessSession.fetch() for empty collection
Signed-off-by: Gavin King <gavin@hibernate.org>
This commit is contained in:
parent
c0d2075ee6
commit
6695617210
|
@ -20,7 +20,6 @@ import org.hibernate.event.spi.InitializeCollectionEventListener;
|
||||||
import org.hibernate.internal.CoreLogging;
|
import org.hibernate.internal.CoreLogging;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.persister.collection.CollectionPersister;
|
import org.hibernate.persister.collection.CollectionPersister;
|
||||||
import org.hibernate.pretty.MessageHelper;
|
|
||||||
import org.hibernate.sql.results.internal.ResultsHelper;
|
import org.hibernate.sql.results.internal.ResultsHelper;
|
||||||
import org.hibernate.stat.spi.StatisticsImplementor;
|
import org.hibernate.stat.spi.StatisticsImplementor;
|
||||||
|
|
||||||
|
@ -39,7 +38,8 @@ public class DefaultInitializeCollectionEventListener implements InitializeColle
|
||||||
final PersistentCollection<?> collection = event.getCollection();
|
final PersistentCollection<?> collection = event.getCollection();
|
||||||
final SessionImplementor source = event.getSession();
|
final SessionImplementor source = event.getSession();
|
||||||
|
|
||||||
final CollectionEntry ce = source.getPersistenceContextInternal().getCollectionEntry( collection );
|
final PersistenceContext persistenceContext = source.getPersistenceContextInternal();
|
||||||
|
final CollectionEntry ce = persistenceContext.getCollectionEntry( collection );
|
||||||
if ( ce == null ) {
|
if ( ce == null ) {
|
||||||
throw new HibernateException( "collection was evicted" );
|
throw new HibernateException( "collection was evicted" );
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ public class DefaultInitializeCollectionEventListener implements InitializeColle
|
||||||
LOG.trace( "Collection not cached" );
|
LOG.trace( "Collection not cached" );
|
||||||
}
|
}
|
||||||
loadedPersister.initialize( loadedKey, source );
|
loadedPersister.initialize( loadedKey, source );
|
||||||
handlePotentiallyEmptyCollection( collection, source, ce, loadedPersister );
|
handlePotentiallyEmptyCollection( collection, persistenceContext, loadedKey, loadedPersister );
|
||||||
if ( LOG.isTraceEnabled() ) {
|
if ( LOG.isTraceEnabled() ) {
|
||||||
LOG.trace( "Collection initialized" );
|
LOG.trace( "Collection initialized" );
|
||||||
}
|
}
|
||||||
|
@ -78,18 +78,18 @@ public class DefaultInitializeCollectionEventListener implements InitializeColle
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handlePotentiallyEmptyCollection(
|
public static void handlePotentiallyEmptyCollection(
|
||||||
PersistentCollection<?> collection,
|
PersistentCollection<?> collection,
|
||||||
SessionImplementor source,
|
PersistenceContext persistenceContext,
|
||||||
CollectionEntry ce,
|
Object loadedKey,
|
||||||
CollectionPersister loadedPersister) {
|
CollectionPersister loadedPersister) {
|
||||||
if ( !collection.wasInitialized() ) {
|
if ( !collection.wasInitialized() ) {
|
||||||
collection.initializeEmptyCollection( loadedPersister );
|
collection.initializeEmptyCollection( loadedPersister );
|
||||||
ResultsHelper.finalizeCollectionLoading(
|
ResultsHelper.finalizeCollectionLoading(
|
||||||
source.getPersistenceContext(),
|
persistenceContext,
|
||||||
loadedPersister,
|
loadedPersister,
|
||||||
collection,
|
collection,
|
||||||
ce.getLoadedKey(),
|
loadedKey,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,7 @@ import static org.hibernate.engine.internal.ManagedTypeHelper.isPersistentAttrib
|
||||||
import static org.hibernate.engine.internal.Versioning.incrementVersion;
|
import static org.hibernate.engine.internal.Versioning.incrementVersion;
|
||||||
import static org.hibernate.engine.internal.Versioning.seedVersion;
|
import static org.hibernate.engine.internal.Versioning.seedVersion;
|
||||||
import static org.hibernate.engine.internal.Versioning.setVersion;
|
import static org.hibernate.engine.internal.Versioning.setVersion;
|
||||||
|
import static org.hibernate.event.internal.DefaultInitializeCollectionEventListener.handlePotentiallyEmptyCollection;
|
||||||
import static org.hibernate.generator.EventType.INSERT;
|
import static org.hibernate.generator.EventType.INSERT;
|
||||||
import static org.hibernate.internal.util.NullnessUtil.castNonNull;
|
import static org.hibernate.internal.util.NullnessUtil.castNonNull;
|
||||||
import static org.hibernate.pretty.MessageHelper.infoString;
|
import static org.hibernate.pretty.MessageHelper.infoString;
|
||||||
|
@ -503,6 +504,8 @@ public class StatelessSessionImpl extends AbstractSharedSessionContract implemen
|
||||||
persistentCollection.setCurrentSession( this );
|
persistentCollection.setCurrentSession( this );
|
||||||
try {
|
try {
|
||||||
collectionDescriptor.initialize( key, this );
|
collectionDescriptor.initialize( key, this );
|
||||||
|
handlePotentiallyEmptyCollection( persistentCollection, getPersistenceContextInternal(), key,
|
||||||
|
collectionDescriptor );
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
persistentCollection.unsetSession( this );
|
persistentCollection.unsetSession( this );
|
||||||
|
|
|
@ -89,6 +89,33 @@ public class FetchTest extends BaseNonConfigCoreFunctionalTestCase {
|
||||||
long count = stats.getPrepareStatementCount();
|
long count = stats.getPrepareStatementCount();
|
||||||
session.fetch( school.students);
|
session.fetch( school.students);
|
||||||
assertTrue( Hibernate.isInitialized( school.students) );
|
assertTrue( Hibernate.isInitialized( school.students) );
|
||||||
|
assertEquals( 1, school.students.size() );
|
||||||
|
|
||||||
|
assertEquals( count+1, stats.getPrepareStatementCount() );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFetchEmpty() {
|
||||||
|
inStatelessTransaction(
|
||||||
|
session -> {
|
||||||
|
Secondary secondary = new Secondary( "BHS" );
|
||||||
|
session.insert(secondary);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
inStatelessSession(
|
||||||
|
session -> {
|
||||||
|
final Statistics stats = sessionFactory().getStatistics();
|
||||||
|
stats.clear();
|
||||||
|
final School school = session.get( School.class, "BHS" );
|
||||||
|
assertFalse( Hibernate.isInitialized( school.students) );
|
||||||
|
assertTrue( school.students instanceof PersistentSet );
|
||||||
|
long count = stats.getPrepareStatementCount();
|
||||||
|
session.fetch( school.students);
|
||||||
|
assertTrue( Hibernate.isInitialized( school.students) );
|
||||||
|
assertTrue( school.students.isEmpty() );
|
||||||
|
|
||||||
assertEquals( count+1, stats.getPrepareStatementCount() );
|
assertEquals( count+1, stats.getPrepareStatementCount() );
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue