trim array holding batch of ids before passing to JDBC

before this, the array length was the batch size, and
was padded with nulls, which isn't great if you have
a large batch size, I suppose
This commit is contained in:
Gavin 2023-05-21 10:02:31 +02:00 committed by Gavin King
parent f2017cd5a0
commit 2926d1781d
3 changed files with 44 additions and 28 deletions

View File

@ -370,15 +370,16 @@ public class BatchFetchQueue {
return; return;
} }
int i = 1; final LinkedHashMap<CollectionEntry, PersistentCollection<?>> map =
int end = -1; batchLoadableCollections.get( pluralAttributeMapping.getNavigableRole().getFullPath() );
boolean checkForEnd = false;
final LinkedHashMap<CollectionEntry, PersistentCollection<?>> map = batchLoadableCollections.get( pluralAttributeMapping.getNavigableRole().getFullPath() );
if ( map == null ) { if ( map == null ) {
return; return;
} }
int i = 1;
int end = -1;
boolean checkForEnd = false;
for ( Entry<CollectionEntry, PersistentCollection<?>> me : map.entrySet() ) { for ( Entry<CollectionEntry, PersistentCollection<?>> me : map.entrySet() ) {
final CollectionEntry ce = me.getKey(); final CollectionEntry ce = me.getKey();
final PersistentCollection<?> collection = me.getValue(); final PersistentCollection<?> collection = me.getValue();

View File

@ -7,6 +7,7 @@
package org.hibernate.loader.ast.internal; package org.hibernate.loader.ast.internal;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.util.Arrays;
import org.hibernate.LockOptions; import org.hibernate.LockOptions;
import org.hibernate.collection.spi.PersistentCollection; import org.hibernate.collection.spi.PersistentCollection;
@ -45,7 +46,6 @@ import static org.hibernate.loader.ast.internal.MultiKeyLoadLogging.MULTI_KEY_LO
public class CollectionBatchLoaderArrayParam public class CollectionBatchLoaderArrayParam
extends AbstractCollectionBatchLoader extends AbstractCollectionBatchLoader
implements CollectionBatchLoader, SqlArrayMultiKeyLoader { implements CollectionBatchLoader, SqlArrayMultiKeyLoader {
private final Class<?> arrayElementType;
private final JdbcMapping arrayJdbcMapping; private final JdbcMapping arrayJdbcMapping;
private final JdbcParameter jdbcParameter; private final JdbcParameter jdbcParameter;
private final SelectStatement sqlSelect; private final SelectStatement sqlSelect;
@ -67,10 +67,10 @@ public class CollectionBatchLoaderArrayParam
); );
} }
final SimpleForeignKeyDescriptor keyDescriptor = (SimpleForeignKeyDescriptor) getLoadable().getKeyDescriptor(); final SimpleForeignKeyDescriptor keyDescriptor = getKeyDescriptor();
arrayElementType = keyDescriptor.getJavaType().getJavaTypeClass(); final Class<?> keyType = keyDescriptor.getJavaType().getJavaTypeClass();
final Class<?> arrayClass = Array.newInstance( arrayElementType, 0 ).getClass(); final Class<?> arrayClass = Array.newInstance( keyType, 0 ).getClass();
final BasicType<?> arrayBasicType = getSessionFactory().getTypeConfiguration() final BasicType<?> arrayBasicType = getSessionFactory().getTypeConfiguration()
.getBasicTypeRegistry() .getBasicTypeRegistry()
@ -101,6 +101,10 @@ public class CollectionBatchLoaderArrayParam
singleKeyLoader = new CollectionLoaderSingleKey( attributeMapping, loadQueryInfluencers, sessionFactory ); singleKeyLoader = new CollectionLoaderSingleKey( attributeMapping, loadQueryInfluencers, sessionFactory );
} }
private SimpleForeignKeyDescriptor getKeyDescriptor() {
return (SimpleForeignKeyDescriptor) getLoadable().getKeyDescriptor();
}
@Override @Override
public PersistentCollection<?> load(Object key, SharedSessionContractImplementor session) { public PersistentCollection<?> load(Object key, SharedSessionContractImplementor session) {
if ( MULTI_KEY_LOAD_DEBUG_ENABLED ) { if ( MULTI_KEY_LOAD_DEBUG_ENABLED ) {
@ -120,14 +124,21 @@ public class CollectionBatchLoaderArrayParam
} }
private Object[] resolveKeysToInitialize(Object keyBeingLoaded, SharedSessionContractImplementor session) { private Object[] resolveKeysToInitialize(Object keyBeingLoaded, SharedSessionContractImplementor session) {
final Object[] keysToInitialize = (Object[]) Array.newInstance( arrayElementType, getDomainBatchSize() ); final int length = getDomainBatchSize();
session.getPersistenceContextInternal().getBatchFetchQueue().collectBatchLoadableCollectionKeys( final Class<?> keyType = getKeyDescriptor().getJavaType().getJavaTypeClass();
getDomainBatchSize(), final Object[] keysToInitialize = (Object[]) Array.newInstance( keyType, length );
(index, value) -> keysToInitialize[index] = value, session.getPersistenceContextInternal().getBatchFetchQueue()
keyBeingLoaded, .collectBatchLoadableCollectionKeys(
getLoadable() length,
); (index, value) -> keysToInitialize[index] = value,
return keysToInitialize; keyBeingLoaded,
getLoadable()
);
int newLength = length;
while ( newLength>1 && keysToInitialize[newLength-1] == null ) {
newLength--;
}
return newLength < length ? Arrays.copyOf( keysToInitialize, newLength ) : keysToInitialize;
} }
private void initializeKeys(Object[] keysToInitialize, SharedSessionContractImplementor session) { private void initializeKeys(Object[] keysToInitialize, SharedSessionContractImplementor session) {
@ -162,7 +173,4 @@ public class CollectionBatchLoaderArrayParam
finishInitializingKey( keysToInitialize[i], session ); finishInitializingKey( keysToInitialize[i], session );
} }
} }
public void prepare() {
}
} }

View File

@ -7,6 +7,7 @@
package org.hibernate.loader.ast.internal; package org.hibernate.loader.ast.internal;
import java.lang.reflect.Array; import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Locale; import java.util.Locale;
import org.hibernate.LockOptions; import org.hibernate.LockOptions;
@ -137,14 +138,20 @@ public class EntityBatchLoaderArrayParam<T>
} }
protected Object[] resolveIdsToInitialize(Object pkValue, SharedSessionContractImplementor session) { protected Object[] resolveIdsToInitialize(Object pkValue, SharedSessionContractImplementor session) {
final Object[] idsToLoad = (Object[]) Array.newInstance( identifierMapping.getJavaType().getJavaTypeClass(), domainBatchSize ); final Class<?> idType = identifierMapping.getJavaType().getJavaTypeClass();
session.getPersistenceContextInternal().getBatchFetchQueue().collectBatchLoadableEntityIds( final Object[] idsToLoad = (Object[]) Array.newInstance( idType, domainBatchSize );
domainBatchSize, session.getPersistenceContextInternal().getBatchFetchQueue()
(index, value) -> idsToLoad[index] = value, .collectBatchLoadableEntityIds(
pkValue, domainBatchSize,
getLoadable() (index, value) -> idsToLoad[index] = value,
); pkValue,
return idsToLoad; getLoadable()
);
int newLength = domainBatchSize;
while ( newLength>1 && idsToLoad[newLength-1] == null ) {
newLength--;
}
return newLength < domainBatchSize ? Arrays.copyOf( idsToLoad, newLength ) : idsToLoad;
} }
private void initializeEntities( private void initializeEntities(