diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/CollectionBatchLoaderArrayParam.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/CollectionBatchLoaderArrayParam.java index 24878a20b6be..e0882da3efd8 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/CollectionBatchLoaderArrayParam.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/CollectionBatchLoaderArrayParam.java @@ -51,7 +51,6 @@ public class CollectionBatchLoaderArrayParam private final SelectStatement sqlSelect; private final JdbcOperationQuerySelect jdbcSelectOperation; - @AllowReflection public CollectionBatchLoaderArrayParam( int domainBatchSize, LoadQueryInfluencers loadQueryInfluencers, @@ -69,13 +68,12 @@ public CollectionBatchLoaderArrayParam( final ForeignKeyDescriptor keyDescriptor = getLoadable().getKeyDescriptor(); final JdbcMapping jdbcMapping = keyDescriptor.getSingleJdbcMapping(); - final Class jdbcArrayClass = Array.newInstance( jdbcMapping.getJdbcJavaType().getJavaTypeClass(), 0 ) - .getClass(); + final Class jdbcJavaTypeClass = jdbcMapping.getJdbcJavaType().getJavaTypeClass(); keyDomainType = getKeyType( keyDescriptor.getKeyPart() ); arrayJdbcMapping = MultiKeyLoadHelper.resolveArrayJdbcMapping( jdbcMapping, - jdbcArrayClass, + jdbcJavaTypeClass, getSessionFactory() ); diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/EntityBatchLoaderArrayParam.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/EntityBatchLoaderArrayParam.java index 4289c88bb1d0..40dfc5839736 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/EntityBatchLoaderArrayParam.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/EntityBatchLoaderArrayParam.java @@ -59,7 +59,6 @@ public class EntityBatchLoaderArrayParam * {@link EntityIdentifierMapping} is not available at that time. On first use, we know we * have it available */ - @AllowReflection public EntityBatchLoaderArrayParam( int domainBatchSize, EntityMappingType entityDescriptor, @@ -77,11 +76,10 @@ public EntityBatchLoaderArrayParam( } identifierMapping = (BasicEntityIdentifierMapping) getLoadable().getIdentifierMapping(); - final Class arrayClass = - Array.newInstance( identifierMapping.getJavaType().getJavaTypeClass(), 0 ).getClass(); + final Class idClass = identifierMapping.getJavaType().getJavaTypeClass(); arrayJdbcMapping = MultiKeyLoadHelper.resolveArrayJdbcMapping( identifierMapping.getJdbcMapping(), - arrayClass, + idClass, sessionFactory ); diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiIdEntityLoaderArrayParam.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiIdEntityLoaderArrayParam.java index d6bb4dbada17..86a40d030da6 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiIdEntityLoaderArrayParam.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiIdEntityLoaderArrayParam.java @@ -49,10 +49,10 @@ public MultiIdEntityLoaderArrayParam( EntityMappingType entityDescriptor, SessionFactoryImplementor sessionFactory) { super( entityDescriptor, sessionFactory ); - final Class idArrayClass = idArray.getClass(); + final Class idClass = idArray.getClass().getComponentType(); arrayJdbcMapping = resolveArrayJdbcMapping( getIdentifierMapping().getJdbcMapping(), - idArrayClass, + idClass, getSessionFactory() ); jdbcParameter = new JdbcParameterImpl( arrayJdbcMapping ); diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiKeyLoadHelper.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiKeyLoadHelper.java index 680158497dec..424578ba8083 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiKeyLoadHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiKeyLoadHelper.java @@ -28,10 +28,10 @@ public static boolean supportsSqlArrayType(Dialect dialect) { public static JdbcMapping resolveArrayJdbcMapping( JdbcMapping keyMapping, - Class arrayClass, + Class elementClass, SessionFactoryImplementor sessionFactory) { BasicType arrayBasicType = sessionFactory.getTypeConfiguration().getBasicTypeRegistry() - .getRegisteredType( arrayClass ); + .getRegisteredArrayType( elementClass ); if ( arrayBasicType != null ) { return arrayBasicType; } @@ -39,9 +39,9 @@ public static JdbcMapping resolveArrayJdbcMapping( final TypeConfiguration typeConfiguration = sessionFactory.getTypeConfiguration(); final JavaTypeRegistry javaTypeRegistry = typeConfiguration.getJavaTypeRegistry(); - final JavaType rawArrayJavaType = javaTypeRegistry.resolveDescriptor( arrayClass ); - if ( !(rawArrayJavaType instanceof BasicPluralJavaType arrayJavaType) ) { - throw new IllegalArgumentException( "Expecting BasicPluralJavaType for array class `" + arrayClass.getName() + "`, but got `" + rawArrayJavaType + "`" ); + final JavaType rawArrayJavaType = javaTypeRegistry.resolveArrayDescriptor( elementClass ); + if ( !(rawArrayJavaType instanceof BasicPluralJavaType arrayJavaType ) ) { + throw new IllegalArgumentException( "Expecting BasicPluralJavaType for array class `" + elementClass.getTypeName() + "[]`, but got `" + rawArrayJavaType + "`" ); } //noinspection unchecked,rawtypes diff --git a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiNaturalIdLoaderArrayParam.java b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiNaturalIdLoaderArrayParam.java index 46ae21542f2c..dad4597ecdb6 100644 --- a/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiNaturalIdLoaderArrayParam.java +++ b/hibernate-core/src/main/java/org/hibernate/loader/ast/internal/MultiNaturalIdLoaderArrayParam.java @@ -29,15 +29,14 @@ */ public class MultiNaturalIdLoaderArrayParam implements MultiNaturalIdLoader, SqlArrayMultiKeyLoader { private final EntityMappingType entityDescriptor; - private final Class keyArrayClass; + private final Class keyClass; public MultiNaturalIdLoaderArrayParam(EntityMappingType entityDescriptor) { assert entityDescriptor.getNaturalIdMapping() instanceof SimpleNaturalIdMapping; this.entityDescriptor = entityDescriptor; - final Class keyClass = entityDescriptor.getNaturalIdMapping().getJavaType().getJavaTypeClass(); - this.keyArrayClass = LoaderHelper.createTypedArray( keyClass, 0 ).getClass(); + this.keyClass = entityDescriptor.getNaturalIdMapping().getJavaType().getJavaTypeClass(); } @Override @@ -77,7 +76,7 @@ public List multiLoad(K[] naturalIds, MultiNaturalIdLoadOptions loadOptio final JdbcMapping arrayJdbcMapping = MultiKeyLoadHelper.resolveArrayJdbcMapping( getNaturalIdMapping().getSingleJdbcMapping(), - keyArrayClass, + keyClass, sessionFactory ); final JdbcParameter jdbcParameter = new JdbcParameterImpl( arrayJdbcMapping ); diff --git a/hibernate-core/src/main/java/org/hibernate/type/BasicTypeRegistry.java b/hibernate-core/src/main/java/org/hibernate/type/BasicTypeRegistry.java index c6f7c197bb09..97354c3f813f 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/BasicTypeRegistry.java +++ b/hibernate-core/src/main/java/org/hibernate/type/BasicTypeRegistry.java @@ -117,6 +117,10 @@ public BasicType getRegisteredType(Class javaType) { return getRegisteredType( javaType.getTypeName() ); } + public BasicType getRegisteredArrayType(java.lang.reflect.Type javaElementType) { + return getRegisteredType( javaElementType.getTypeName() + "[]" ); + } + public BasicType resolve(BasicTypeReference basicTypeReference) { return getRegisteredType( basicTypeReference.getName() ); } diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/JavaTypeRegistry.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/JavaTypeRegistry.java index c54b21539503..641cd428e0bc 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/JavaTypeRegistry.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/spi/JavaTypeRegistry.java @@ -34,7 +34,7 @@ public class JavaTypeRegistry implements JavaTypeBaseline.BaselineTarget, Serial private static final Logger log = Logger.getLogger( JavaTypeRegistry.class ); private final TypeConfiguration typeConfiguration; - private final ConcurrentHashMap> descriptorsByType = new ConcurrentHashMap<>(); + private final ConcurrentHashMap> descriptorsByTypeName = new ConcurrentHashMap<>(); public JavaTypeRegistry(TypeConfiguration typeConfiguration) { this.typeConfiguration = typeConfiguration; @@ -56,7 +56,7 @@ public void addBaselineDescriptor(JavaType descriptor) { @Override public void addBaselineDescriptor(Type describedJavaType, JavaType descriptor) { performInjections( descriptor ); - descriptorsByType.put( describedJavaType, descriptor ); + descriptorsByTypeName.put( describedJavaType.getTypeName(), descriptor ); } private void performInjections(JavaType descriptor) { @@ -71,7 +71,7 @@ private void performInjections(JavaType descriptor) { // descriptor access public void forEachDescriptor(Consumer> consumer) { - descriptorsByType.values().forEach( consumer ); + descriptorsByTypeName.values().forEach( consumer ); } public JavaType getDescriptor(Type javaType) { @@ -79,7 +79,7 @@ public JavaType getDescriptor(Type javaType) { } public void addDescriptor(JavaType descriptor) { - JavaType old = descriptorsByType.put( descriptor.getJavaType(), descriptor ); + JavaType old = descriptorsByTypeName.put( descriptor.getJavaType().getTypeName(), descriptor ); if ( old != null ) { log.debugf( "JavaTypeRegistry entry replaced : %s -> %s (was %s)", @@ -93,40 +93,51 @@ public void addDescriptor(JavaType descriptor) { public JavaType findDescriptor(Type javaType) { //noinspection unchecked - return (JavaType) descriptorsByType.get( javaType ); + return (JavaType) descriptorsByTypeName.get( javaType.getTypeName() ); } public JavaType resolveDescriptor(Type javaType, Supplier> creator) { - final JavaType cached = descriptorsByType.get( javaType ); + return resolveDescriptor( javaType.getTypeName(), creator ); + } + + private JavaType resolveDescriptor(String javaTypeName, Supplier> creator) { + final JavaType cached = descriptorsByTypeName.get( javaTypeName ); if ( cached != null ) { //noinspection unchecked return (JavaType) cached; } final JavaType created = creator.get(); - descriptorsByType.put( javaType, created ); + descriptorsByTypeName.put( javaTypeName, created ); return created; } public JavaType resolveDescriptor(Type javaType) { - return resolveDescriptor( javaType, (elementJavaType, typeConfiguration) -> { - final MutabilityPlan determinedPlan = RegistryHelper.INSTANCE.determineMutabilityPlan( - elementJavaType, - typeConfiguration - ); - if ( determinedPlan != null ) { - return determinedPlan; - } + return resolveDescriptor( javaType, JavaTypeRegistry::createMutabilityPlan ); + } + + private static MutabilityPlan createMutabilityPlan(Type elementJavaType, TypeConfiguration typeConfiguration) { + final MutabilityPlan determinedPlan = RegistryHelper.INSTANCE.determineMutabilityPlan( + elementJavaType, + typeConfiguration + ); + if ( determinedPlan != null ) { + return determinedPlan; + } + + return MutableMutabilityPlan.INSTANCE; + } - return MutableMutabilityPlan.INSTANCE; - } ); + public JavaType resolveArrayDescriptor(Class elementJavaType) { + return resolveDescriptor( elementJavaType.getTypeName() + "[]", + () -> createArrayTypeDescriptor( elementJavaType, JavaTypeRegistry::createMutabilityPlan) ); } public JavaType resolveDescriptor( Type javaType, BiFunction> mutabilityPlanCreator) { return resolveDescriptor( - javaType, + javaType.getTypeName(), () -> { if ( javaType instanceof ParameterizedType parameterizedType ) { final JavaType rawType = findDescriptor( parameterizedType.getRawType() ); @@ -134,33 +145,32 @@ public JavaType resolveDescriptor( return rawType.createJavaType( parameterizedType, typeConfiguration ); } } - final Type elementJavaType; - JavaType elementTypeDescriptor; - if ( javaType instanceof Class && ( (Class) javaType ).isArray() ) { - elementJavaType = ( (Class) javaType ).getComponentType(); - elementTypeDescriptor = findDescriptor( elementJavaType ); - } - else { - elementJavaType = javaType; - elementTypeDescriptor = null; - } - if ( elementTypeDescriptor == null ) { - //noinspection unchecked - elementTypeDescriptor = RegistryHelper.INSTANCE.createTypeDescriptor( - elementJavaType, - () -> (MutabilityPlan) mutabilityPlanCreator.apply( elementJavaType, typeConfiguration ), - typeConfiguration - ); - } - if ( javaType != elementJavaType ) { + else if ( javaType instanceof Class javaClass && javaClass.isArray() ) { //noinspection unchecked - return (JavaType) new ArrayJavaType<>( elementTypeDescriptor ); + return (JavaType) createArrayTypeDescriptor( javaClass.getComponentType(), mutabilityPlanCreator ); } - return elementTypeDescriptor; + return createTypeDescriptor( javaType, mutabilityPlanCreator ); } ); } + private JavaType createArrayTypeDescriptor(Class elementJavaType, BiFunction> mutabilityPlanCreator) { + JavaType elementTypeDescriptor = findDescriptor( elementJavaType ); + if ( elementTypeDescriptor == null ) { + elementTypeDescriptor = createTypeDescriptor( elementJavaType, mutabilityPlanCreator ); + } + return new ArrayJavaType<>( elementTypeDescriptor ); + } + + private JavaType createTypeDescriptor(Type javaType, BiFunction> mutabilityPlanCreator) { + //noinspection unchecked + return RegistryHelper.INSTANCE.createTypeDescriptor( + javaType, + () -> (MutabilityPlan) mutabilityPlanCreator.apply( javaType, typeConfiguration ), + typeConfiguration + ); + } + public JavaType resolveManagedTypeDescriptor(Type javaType) { return resolveManagedTypeDescriptor( javaType, false ); }