HHH-14312 - entity graph is ignored for 'padded' and 'dynamic' batch style entity loader

- completed fix for HHH-11970
This commit is contained in:
Steve Ebersole 2020-11-11 07:55:41 -06:00
parent 13fb23d44e
commit 0b2fb4e28b
3 changed files with 25 additions and 7 deletions

View File

@ -12,7 +12,6 @@ import java.util.List;
import org.hibernate.LockOptions; import org.hibernate.LockOptions;
import org.hibernate.engine.internal.BatchFetchQueueHelper; import org.hibernate.engine.internal.BatchFetchQueueHelper;
import org.hibernate.engine.spi.LoadQueryInfluencers; import org.hibernate.engine.spi.LoadQueryInfluencers;
import org.hibernate.engine.spi.QueryParameters;
import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.internal.util.collections.ArrayHelper;
@ -69,11 +68,8 @@ public class DynamicBatchingEntityLoader extends BatchingEntityLoader {
} }
final EntityLoader dynamicLoader = entityLoaderBuilder.withBatchSize( idsToLoad.length ).byPrimaryKey(); final EntityLoader dynamicLoader = entityLoaderBuilder.withBatchSize( idsToLoad.length ).byPrimaryKey();
final QueryParameters qp = buildQueryParameters( id, idsToLoad, optionalObject, lockOptions );
final List<?> results = dynamicLoader.loadEntityBatch(
final List results = dynamicLoader.loadEntityBatch(
session, session,
idsToLoad, idsToLoad,
persister().getIdentifierType(), persister().getIdentifierType(),

View File

@ -16,6 +16,7 @@ import org.hibernate.engine.spi.LoadQueryInfluencers;
import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.collections.ArrayHelper; import org.hibernate.internal.util.collections.ArrayHelper;
import org.hibernate.loader.entity.UniqueEntityLoader;
import org.hibernate.persister.entity.OuterJoinLoadable; import org.hibernate.persister.entity.OuterJoinLoadable;
/** /**
@ -59,6 +60,11 @@ public class PaddedBatchingEntityLoader extends BatchingEntityLoader {
} }
} }
@Override
public Object load(Serializable id, Object optionalObject, SharedSessionContractImplementor session) {
return load( id, optionalObject, session, LockOptions.NONE, null );
}
@Override @Override
public Object load( public Object load(
Serializable id, Serializable id,
@ -76,6 +82,16 @@ public class PaddedBatchingEntityLoader extends BatchingEntityLoader {
final int numberOfIds = ArrayHelper.countNonNull( batch ); final int numberOfIds = ArrayHelper.countNonNull( batch );
if ( numberOfIds <= 1 ) {
final Object result = ( (UniqueEntityLoader) loaders[batchSizes.length-1] ).load( id, optionalObject, session, lockOptions );
if ( result == null ) {
// There was no entity with the specified ID. Make sure the EntityKey does not remain
// in the batch to avoid including it in future batches that get executed.
BatchFetchQueueHelper.removeBatchLoadableEntityKey( id, persister(), session );
}
return result;
}
// Uses the first batch-size bigger than the number of actual ids in the batch // Uses the first batch-size bigger than the number of actual ids in the batch
int indexToUse = batchSizes.length-1; int indexToUse = batchSizes.length-1;
for ( int i = 0; i < batchSizes.length-1; i++ ) { for ( int i = 0; i < batchSizes.length-1; i++ ) {
@ -93,7 +109,7 @@ public class PaddedBatchingEntityLoader extends BatchingEntityLoader {
idsToLoad[i] = id; idsToLoad[i] = id;
} }
final List results = loaders[indexToUse].loadEntityBatch( final List<?> results = loaders[indexToUse].loadEntityBatch(
session, session,
idsToLoad, idsToLoad,
persister().getIdentifierType(), persister().getIdentifierType(),

View File

@ -32,6 +32,8 @@ import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate; import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
@ -284,7 +286,11 @@ public class BatchFetchNotFoundIgnoreDefaultStyleTest extends BaseCoreFunctional
sessionImplementor.getFactory().getMetamodel().entityPersister( Task.class ); sessionImplementor.getFactory().getMetamodel().entityPersister( Task.class );
final BatchFetchQueue batchFetchQueue = final BatchFetchQueue batchFetchQueue =
sessionImplementor.getPersistenceContextInternal().getBatchFetchQueue(); sessionImplementor.getPersistenceContextInternal().getBatchFetchQueue();
assertEquals( expected, batchFetchQueue.containsEntityKey( new EntityKey( id, persister ) ) ); assertThat(
"Checking BatchFetchQueue for entry for Task#" + id,
batchFetchQueue.containsEntityKey( new EntityKey( id, persister ) ),
is( expected )
);
} }
@Entity(name = "Employee") @Entity(name = "Employee")