HHH-17202 Fix ArrayStoreException for single field id class entity collection batch loading
This commit is contained in:
parent
a27d7994a6
commit
30687e0370
|
@ -19,7 +19,10 @@ import org.hibernate.loader.ast.spi.CollectionBatchLoader;
|
|||
import org.hibernate.loader.ast.spi.SqlArrayMultiKeyLoader;
|
||||
import org.hibernate.metamodel.mapping.ForeignKeyDescriptor;
|
||||
import org.hibernate.metamodel.mapping.JdbcMapping;
|
||||
import org.hibernate.metamodel.mapping.NonAggregatedIdentifierMapping;
|
||||
import org.hibernate.metamodel.mapping.PluralAttributeMapping;
|
||||
import org.hibernate.metamodel.mapping.ValuedModelPart;
|
||||
import org.hibernate.metamodel.mapping.internal.IdClassEmbeddable;
|
||||
import org.hibernate.query.spi.QueryOptions;
|
||||
import org.hibernate.sql.ast.tree.expression.JdbcParameter;
|
||||
import org.hibernate.sql.ast.tree.select.SelectStatement;
|
||||
|
@ -43,7 +46,7 @@ import static org.hibernate.loader.ast.internal.MultiKeyLoadLogging.MULTI_KEY_LO
|
|||
public class CollectionBatchLoaderArrayParam
|
||||
extends AbstractCollectionBatchLoader
|
||||
implements CollectionBatchLoader, SqlArrayMultiKeyLoader {
|
||||
private final Class<?> arrayElementType;
|
||||
private final Class<?> keyDomainType;
|
||||
private final JdbcMapping arrayJdbcMapping;
|
||||
private final JdbcParameter jdbcParameter;
|
||||
private final SelectStatement sqlSelect;
|
||||
|
@ -65,17 +68,18 @@ public class CollectionBatchLoaderArrayParam
|
|||
}
|
||||
|
||||
final ForeignKeyDescriptor keyDescriptor = getLoadable().getKeyDescriptor();
|
||||
|
||||
arrayElementType = keyDescriptor.getJavaType().getJavaTypeClass();
|
||||
Class<?> arrayClass = Array.newInstance( arrayElementType, 0 ).getClass();
|
||||
final JdbcMapping jdbcMapping = keyDescriptor.getSingleJdbcMapping();
|
||||
final Class<?> jdbcArrayClass = Array.newInstance( jdbcMapping.getJdbcJavaType().getJavaTypeClass(), 0 )
|
||||
.getClass();
|
||||
keyDomainType = getKeyType( keyDescriptor.getKeyPart() );
|
||||
|
||||
final BasicType<?> arrayBasicType = getSessionFactory().getTypeConfiguration()
|
||||
.getBasicTypeRegistry()
|
||||
.getRegisteredType( arrayClass );
|
||||
.getRegisteredType( jdbcArrayClass );
|
||||
arrayJdbcMapping = MultiKeyLoadHelper.resolveArrayJdbcMapping(
|
||||
arrayBasicType,
|
||||
keyDescriptor.getSingleJdbcMapping(),
|
||||
arrayClass,
|
||||
jdbcMapping,
|
||||
jdbcArrayClass,
|
||||
getSessionFactory()
|
||||
);
|
||||
|
||||
|
@ -96,6 +100,16 @@ public class CollectionBatchLoaderArrayParam
|
|||
.translate( JdbcParameterBindings.NO_BINDINGS, QueryOptions.NONE );
|
||||
}
|
||||
|
||||
private Class<?> getKeyType(ValuedModelPart keyPart) {
|
||||
if ( keyPart instanceof NonAggregatedIdentifierMapping ) {
|
||||
final IdClassEmbeddable idClassEmbeddable = ( (NonAggregatedIdentifierMapping) keyPart ).getIdClassEmbeddable();
|
||||
if ( idClassEmbeddable != null ) {
|
||||
return idClassEmbeddable.getMappedJavaType().getJavaTypeClass();
|
||||
}
|
||||
}
|
||||
return keyPart.getJavaType().getJavaTypeClass();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PersistentCollection<?> load(Object key, SharedSessionContractImplementor session) {
|
||||
if ( MULTI_KEY_LOAD_LOGGER.isDebugEnabled() ) {
|
||||
|
@ -126,20 +140,21 @@ public class CollectionBatchLoaderArrayParam
|
|||
ForeignKeyDescriptor keyDescriptor) {
|
||||
|
||||
final int length = getDomainBatchSize();
|
||||
final Object[] keysToInitialize = (Object[]) Array.newInstance(
|
||||
keyDescriptor.getSingleJdbcMapping().getJdbcJavaType().getJavaTypeClass(),
|
||||
length
|
||||
);
|
||||
final Object[] embeddedKeys = (Object[]) Array.newInstance(
|
||||
arrayElementType,
|
||||
final Object[] jdbcKeysToInitialize = (Object[]) Array.newInstance(
|
||||
jdbcParameter.getExpressionType()
|
||||
.getSingleJdbcMapping()
|
||||
.getJdbcJavaType()
|
||||
.getJavaTypeClass()
|
||||
.getComponentType(),
|
||||
length
|
||||
);
|
||||
final Object[] embeddedKeys = (Object[]) Array.newInstance( keyDomainType, length );
|
||||
session.getPersistenceContextInternal().getBatchFetchQueue()
|
||||
.collectBatchLoadableCollectionKeys(
|
||||
length,
|
||||
(index, key) ->
|
||||
keyDescriptor.forEachJdbcValue( key, (i, value, jdbcMapping) -> {
|
||||
keysToInitialize[index] = value;
|
||||
jdbcKeysToInitialize[index] = value;
|
||||
embeddedKeys[index] = key;
|
||||
}, session )
|
||||
,
|
||||
|
@ -147,21 +162,21 @@ public class CollectionBatchLoaderArrayParam
|
|||
getLoadable()
|
||||
);
|
||||
|
||||
initializeKeys( keysToInitialize, session );
|
||||
initializeKeys( jdbcKeysToInitialize, session );
|
||||
|
||||
for ( Object initializedKey : embeddedKeys ) {
|
||||
finishInitializingKey( initializedKey, session );
|
||||
finishInitializingKey( initializedKey, session );
|
||||
}
|
||||
|
||||
final CollectionKey collectionKey = new CollectionKey(
|
||||
getLoadable().getCollectionDescriptor(),
|
||||
keysToInitialize
|
||||
keyBeingLoaded
|
||||
);
|
||||
return session.getPersistenceContext().getCollection( collectionKey );
|
||||
}
|
||||
|
||||
private Object[] resolveKeysToInitialize(Object keyBeingLoaded, SharedSessionContractImplementor session) {
|
||||
final Object[] keysToInitialize = (Object[]) Array.newInstance( arrayElementType, getDomainBatchSize() );
|
||||
final Object[] keysToInitialize = (Object[]) Array.newInstance( keyDomainType, getDomainBatchSize() );
|
||||
session.getPersistenceContextInternal().getBatchFetchQueue().collectBatchLoadableCollectionKeys(
|
||||
getDomainBatchSize(),
|
||||
(index, value) -> keysToInitialize[index] = value,
|
||||
|
|
Loading…
Reference in New Issue