org.hibernate.loader.entity.PaddedBatchingEntityLoaderBuilder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of hibernate-core Show documentation
Show all versions of hibernate-core Show documentation
JPMS Module-Info's for a few of the Jakarta Libraries just until they add them in themselves
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or .
*/
package org.hibernate.loader.entity;
import java.io.Serializable;
import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.LockOptions;
import org.hibernate.engine.internal.BatchFetchQueueHelper;
import org.hibernate.engine.spi.LoadQueryInfluencers;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.engine.spi.SharedSessionContractImplementor;
import org.hibernate.internal.util.collections.ArrayHelper;
import org.hibernate.loader.Loader;
import org.hibernate.persister.entity.OuterJoinLoadable;
/**
* @author Steve Ebersole
*/
class PaddedBatchingEntityLoaderBuilder extends BatchingEntityLoaderBuilder {
public static final PaddedBatchingEntityLoaderBuilder INSTANCE = new PaddedBatchingEntityLoaderBuilder();
@Override
protected UniqueEntityLoader buildBatchingLoader(
OuterJoinLoadable persister,
int batchSize,
LockMode lockMode,
SessionFactoryImplementor factory,
LoadQueryInfluencers influencers) {
return new PaddedBatchingEntityLoader( persister, batchSize, lockMode, factory, influencers );
}
@Override
protected UniqueEntityLoader buildBatchingLoader(
OuterJoinLoadable persister,
int batchSize,
LockOptions lockOptions,
SessionFactoryImplementor factory,
LoadQueryInfluencers influencers) {
return new PaddedBatchingEntityLoader( persister, batchSize, lockOptions, factory, influencers );
}
public static class PaddedBatchingEntityLoader extends BatchingEntityLoader {
private final int[] batchSizes;
private final Loader[] loaders;
public PaddedBatchingEntityLoader(
OuterJoinLoadable persister,
int maxBatchSize,
LockMode lockMode,
SessionFactoryImplementor factory,
LoadQueryInfluencers loadQueryInfluencers) {
super( persister );
this.batchSizes = ArrayHelper.getBatchSizes( maxBatchSize );
this.loaders = new Loader[ batchSizes.length ];
for ( int i = 0; i < batchSizes.length; i++ ) {
this.loaders[i] = new EntityLoader( persister, batchSizes[i], lockMode, factory, loadQueryInfluencers);
}
validate( maxBatchSize );
}
private void validate(int max) {
// these are more indicative of internal problems then user error...
if ( batchSizes[0] != max ) {
throw new HibernateException( "Unexpected batch size spread" );
}
if ( batchSizes[batchSizes.length-1] != 1 ) {
throw new HibernateException( "Unexpected batch size spread" );
}
}
public PaddedBatchingEntityLoader(
OuterJoinLoadable persister,
int maxBatchSize,
LockOptions lockOptions,
SessionFactoryImplementor factory,
LoadQueryInfluencers loadQueryInfluencers) {
super( persister );
this.batchSizes = ArrayHelper.getBatchSizes( maxBatchSize );
this.loaders = new Loader[ batchSizes.length ];
for ( int i = 0; i < batchSizes.length; i++ ) {
this.loaders[i] = new EntityLoader( persister, batchSizes[i], lockOptions, factory, loadQueryInfluencers);
}
validate( maxBatchSize );
}
@Override
public Object load(Serializable id, Object optionalObject, SharedSessionContractImplementor session, LockOptions lockOptions) {
return load( id, optionalObject, session, lockOptions, null );
}
@Override
public Object load(Serializable id, Object optionalObject, SharedSessionContractImplementor session, LockOptions lockOptions, Boolean readOnly) {
final Serializable[] batch = session.getPersistenceContextInternal()
.getBatchFetchQueue()
.getEntityBatch( persister(), id, batchSizes[0], persister().getEntityMode() );
final int numberOfIds = ArrayHelper.countNonNull( batch );
if ( numberOfIds <= 1 ) {
final Object result = ( (UniqueEntityLoader) loaders[batchSizes.length-1] ).load( id, optionalObject, session );
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
int indexToUse = batchSizes.length-1;
for ( int i = 0; i < batchSizes.length-1; i++ ) {
if ( batchSizes[i] >= numberOfIds ) {
indexToUse = i;
}
else {
break;
}
}
final Serializable[] idsToLoad = new Serializable[ batchSizes[indexToUse] ];
System.arraycopy( batch, 0, idsToLoad, 0, numberOfIds );
for ( int i = numberOfIds; i < batchSizes[indexToUse]; i++ ) {
idsToLoad[i] = id;
}
return doBatchLoad( id, loaders[indexToUse], session, idsToLoad, optionalObject, lockOptions, readOnly );
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy