HHH-17078 Register/Deregister load context on every scroll operation

This commit is contained in:
Christian Beikov 2023-08-15 15:34:42 +02:00
parent 981ccc813e
commit 1c86d94a15
4 changed files with 41 additions and 26 deletions

View File

@ -8,6 +8,7 @@ package org.hibernate.internal;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.engine.spi.EntityKey; import org.hibernate.engine.spi.EntityKey;
import org.hibernate.engine.spi.PersistenceContext;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.sql.results.graph.Initializer; import org.hibernate.sql.results.graph.Initializer;
import org.hibernate.sql.results.graph.entity.EntityInitializer; import org.hibernate.sql.results.graph.entity.EntityInitializer;
@ -15,6 +16,7 @@ import org.hibernate.sql.results.internal.RowProcessingStateStandardImpl;
import org.hibernate.sql.results.jdbc.internal.JdbcValuesSourceProcessingStateStandardImpl; import org.hibernate.sql.results.jdbc.internal.JdbcValuesSourceProcessingStateStandardImpl;
import org.hibernate.sql.results.jdbc.spi.JdbcValues; import org.hibernate.sql.results.jdbc.spi.JdbcValues;
import org.hibernate.sql.results.jdbc.spi.JdbcValuesSourceProcessingOptions; import org.hibernate.sql.results.jdbc.spi.JdbcValuesSourceProcessingOptions;
import org.hibernate.sql.results.spi.LoadContexts;
import org.hibernate.sql.results.spi.RowReader; import org.hibernate.sql.results.spi.RowReader;
/** /**
@ -299,8 +301,9 @@ public class FetchingScrollableResultsImpl<R> extends AbstractScrollableResults<
} }
private boolean prepareCurrentRow() { private boolean prepareCurrentRow() {
if ( getRowProcessingState().isBeforeFirst() ) { final RowProcessingStateStandardImpl rowProcessingState = getRowProcessingState();
getRowProcessingState().next(); if ( rowProcessingState.isBeforeFirst() ) {
rowProcessingState.next();
} }
final RowReader<R> rowReader = getRowReader(); final RowReader<R> rowReader = getRowReader();
@ -309,32 +312,43 @@ public class FetchingScrollableResultsImpl<R> extends AbstractScrollableResults<
boolean resultProcessed = false; boolean resultProcessed = false;
final EntityKey entityKey = getEntityKey(); final EntityKey entityKey = getEntityKey();
final PersistenceContext persistenceContext = rowProcessingState.getSession().getPersistenceContext();
final LoadContexts loadContexts = persistenceContext.getLoadContexts();
currentRow = rowReader.readRow( getRowProcessingState(), getProcessingOptions() ); loadContexts.register( getJdbcValuesSourceProcessingState() );
persistenceContext.beforeLoad();
try {
currentRow = rowReader.readRow( rowProcessingState, getProcessingOptions() );
getRowProcessingState().finishRowProcessing(); rowProcessingState.finishRowProcessing();
while ( !resultProcessed ) { while ( !resultProcessed ) {
if ( getRowProcessingState().next() ) { if ( rowProcessingState.next() ) {
final EntityKey entityKey2 = getEntityKey(); final EntityKey entityKey2 = getEntityKey();
if ( !entityKey.equals( entityKey2 ) ) { if ( !entityKey.equals( entityKey2 ) ) {
resultInitializer.finishUpRow( getRowProcessingState() ); resultInitializer.finishUpRow( rowProcessingState );
resultProcessed = true; resultProcessed = true;
afterLast = false; afterLast = false;
}
else {
rowReader.readRow( rowProcessingState, getProcessingOptions() );
rowProcessingState.finishRowProcessing();
}
} }
else { else {
rowReader.readRow( getRowProcessingState(), getProcessingOptions() ); afterLast = true;
getRowProcessingState().finishRowProcessing(); resultProcessed = true;
} }
}
else {
afterLast = true;
resultProcessed = true;
}
}
getJdbcValuesSourceProcessingState().finishUp();
} }
getJdbcValuesSourceProcessingState().finishUp(); finally {
getRowProcessingState().getSession().getPersistenceContext().initializeNonLazyCollections(); persistenceContext.afterLoad();
loadContexts.deregister( getJdbcValuesSourceProcessingState() );
}
persistenceContext.initializeNonLazyCollections();
afterScrollOperation();
return afterLast; return afterLast;
} }

View File

@ -13,6 +13,7 @@ import org.hibernate.sql.results.internal.RowProcessingStateStandardImpl;
import org.hibernate.sql.results.jdbc.internal.JdbcValuesSourceProcessingStateStandardImpl; import org.hibernate.sql.results.jdbc.internal.JdbcValuesSourceProcessingStateStandardImpl;
import org.hibernate.sql.results.jdbc.spi.JdbcValues; import org.hibernate.sql.results.jdbc.spi.JdbcValues;
import org.hibernate.sql.results.jdbc.spi.JdbcValuesSourceProcessingOptions; import org.hibernate.sql.results.jdbc.spi.JdbcValuesSourceProcessingOptions;
import org.hibernate.sql.results.spi.LoadContexts;
import org.hibernate.sql.results.spi.RowReader; import org.hibernate.sql.results.spi.RowReader;
/** /**
@ -124,19 +125,18 @@ public class ScrollableResultsImpl<R> extends AbstractScrollableResults<R> {
} }
final PersistenceContext persistenceContext = getPersistenceContext().getPersistenceContext(); final PersistenceContext persistenceContext = getPersistenceContext().getPersistenceContext();
final LoadContexts loadContexts = persistenceContext.getLoadContexts();
loadContexts.register( getJdbcValuesSourceProcessingState() );
persistenceContext.beforeLoad(); persistenceContext.beforeLoad();
try { try {
currentRow = getRowReader().readRow( currentRow = getRowReader().readRow( getRowProcessingState(), getProcessingOptions() );
getRowProcessingState(),
getProcessingOptions()
);
getRowProcessingState().finishRowProcessing(); getRowProcessingState().finishRowProcessing();
getJdbcValuesSourceProcessingState().finishUp(); getJdbcValuesSourceProcessingState().finishUp();
} }
finally { finally {
persistenceContext.afterLoad(); persistenceContext.afterLoad();
loadContexts.deregister( getJdbcValuesSourceProcessingState() );
} }
persistenceContext.initializeNonLazyCollections(); persistenceContext.initializeNonLazyCollections();

View File

@ -42,7 +42,6 @@ public class ScrollableResultsConsumer<R> implements ResultsConsumer<ScrollableR
JdbcValuesSourceProcessingStateStandardImpl jdbcValuesSourceProcessingState, JdbcValuesSourceProcessingStateStandardImpl jdbcValuesSourceProcessingState,
RowProcessingStateStandardImpl rowProcessingState, RowProcessingStateStandardImpl rowProcessingState,
RowReader<R> rowReader) { RowReader<R> rowReader) {
session.getPersistenceContext().getLoadContexts().register( jdbcValuesSourceProcessingState );
if ( containsCollectionFetches( jdbcValues.getValuesMapping() ) ) { if ( containsCollectionFetches( jdbcValues.getValuesMapping() ) ) {
return new FetchingScrollableResultsImpl<>( return new FetchingScrollableResultsImpl<>(
jdbcValues, jdbcValues,

View File

@ -64,6 +64,8 @@ public class ScrollTest {
s.delete( i1 ); s.delete( i1 );
s.delete( i2 ); s.delete( i2 );
} }
assertTrue( s.getPersistenceContext().getLoadContexts().isLoadingFinished() );
} }
); );