diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/TypeDefinition.java b/hibernate-core/src/main/java/org/hibernate/boot/model/TypeDefinition.java index 6e446ea5e2..c90560b92b 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/TypeDefinition.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/TypeDefinition.java @@ -14,6 +14,7 @@ import java.util.Map; import java.util.Objects; import java.util.Properties; import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Consumer; import java.util.function.Supplier; import org.hibernate.boot.model.process.internal.UserTypeResolution; @@ -162,25 +163,27 @@ public class TypeDefinition implements Serializable { ( (TypeConfigurationAware) typeInstance ).setTypeConfiguration( typeConfiguration ); } - injectParameters( - typeInstance, - () -> { - if ( CollectionHelper.isNotEmpty( usageSiteProperties ) ) { - final Properties properties = new Properties( parameters ); - properties.putAll( usageSiteProperties ); - return properties; - } - else { - return parameters; - } - } - ); + final Properties combinedTypeParameters; + + if ( CollectionHelper.isNotEmpty( usageSiteProperties ) ) { + combinedTypeParameters = new Properties( parameters ); + combinedTypeParameters.putAll( usageSiteProperties ); + } + else { + combinedTypeParameters = parameters; + } + + if ( typeInstance instanceof ParameterizedType ) { + if ( combinedTypeParameters != null ) { + ( (ParameterizedType) typeInstance ).setParameterValues( combinedTypeParameters ); + } + } if ( typeInstance instanceof UserType ) { final UserType userType = (UserType) typeInstance; final CustomType customType = new CustomType( userType, typeConfiguration ); - return new UserTypeResolution( customType, null ); + return new UserTypeResolution( customType, null, combinedTypeParameters ); } if ( typeInstance instanceof BasicType ) { @@ -196,6 +199,11 @@ public class TypeDefinition implements Serializable { return resolvedBasicType; } + @Override + public Properties getCombinedTypeParameters() { + return combinedTypeParameters; + } + @Override public JavaTypeDescriptor getDomainJavaDescriptor() { return resolvedBasicType.getMappedJavaTypeDescriptor(); @@ -283,15 +291,6 @@ public class TypeDefinition implements Serializable { ); } - public static void injectParameters(Object customType, Supplier parameterSupplier) { - if ( customType instanceof ParameterizedType ) { - final Properties parameterValues = parameterSupplier.get(); - if ( parameterValues != null ) { - ( (ParameterizedType) customType ).setParameterValues( parameterValues ); - } - } - } - public static BasicValue.Resolution createLocalResolution( String name, Class typeImplementorClass, diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/process/internal/UserTypeResolution.java b/hibernate-core/src/main/java/org/hibernate/boot/model/process/internal/UserTypeResolution.java index 7dd515eb96..5f10e33aed 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/process/internal/UserTypeResolution.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/process/internal/UserTypeResolution.java @@ -6,6 +6,8 @@ */ package org.hibernate.boot.model.process.internal; +import java.util.Properties; + import org.hibernate.mapping.BasicValue; import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.metamodel.model.convert.spi.BasicValueConverter; @@ -22,10 +24,14 @@ public class UserTypeResolution implements BasicValue.Resolution { private final CustomType userTypeAdapter; private final MutabilityPlan mutabilityPlan; + private final Properties combinedTypeParameters; + public UserTypeResolution( CustomType userTypeAdapter, - MutabilityPlan explicitMutabilityPlan) { + MutabilityPlan explicitMutabilityPlan, + Properties combinedTypeParameters) { this.userTypeAdapter = userTypeAdapter; + this.combinedTypeParameters = combinedTypeParameters; this.mutabilityPlan = explicitMutabilityPlan != null ? explicitMutabilityPlan : new UserTypeMutabilityPlanAdapter( userTypeAdapter.getUserType() ); @@ -61,6 +67,11 @@ public class UserTypeResolution implements BasicValue.Resolution { return userTypeAdapter; } + @Override + public Properties getCombinedTypeParameters() { + return combinedTypeParameters; + } + @Override public JdbcMapping getJdbcMapping() { return userTypeAdapter; diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/hbm/ModelBinder.java b/hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/hbm/ModelBinder.java index feb1478e23..3eb448b0c6 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/hbm/ModelBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/hbm/ModelBinder.java @@ -159,6 +159,7 @@ import org.hibernate.type.DiscriminatorType; import org.hibernate.type.ForeignKeyDirection; import org.hibernate.type.NClobType; import org.hibernate.type.StandardBasicTypes; +import org.hibernate.usertype.ParameterizedType; import org.hibernate.usertype.UserType; import static org.hibernate.internal.util.collections.CollectionHelper.isEmpty; @@ -2400,7 +2401,8 @@ public class ModelBinder { discriminatorTypeName = discriminatorTypeResolution.typeName; discriminatorType = resolveExplicitlyNamedAnyDiscriminatorType( discriminatorTypeResolution.typeName, - discriminatorTypeResolution.parameters + discriminatorTypeResolution.parameters, + anyBinding.getMetaMapping() ); } else { @@ -2456,7 +2458,10 @@ public class ModelBinder { ); } - private DiscriminatorType resolveExplicitlyNamedAnyDiscriminatorType(String typeName, Properties parameters) { + private DiscriminatorType resolveExplicitlyNamedAnyDiscriminatorType( + String typeName, + Properties parameters, + Any.MetaValue discriminatorMapping) { final BootstrapContext bootstrapContext = metadataBuildingContext.getBootstrapContext(); if ( isEmpty( parameters ) ) { @@ -2480,6 +2485,10 @@ public class ModelBinder { bootstrapContext.getTypeConfiguration().getCurrentBaseSqlTypeIndicators() ); + if ( resolution.getCombinedTypeParameters() != null ) { + discriminatorMapping.setTypeParameters( resolution.getCombinedTypeParameters() ); + } + return (DiscriminatorType) resolution.getLegacyResolvedBasicType(); } @@ -2496,7 +2505,12 @@ public class ModelBinder { .getService( ManagedBeanRegistry.class ); final ManagedBean bean = beanRegistry.getBean( beanName, typeJavaType ); final Object typeInstance = bean.getBeanInstance(); - TypeDefinition.injectParameters( typeInstance, () -> parameters ); + + if ( typeInstance instanceof ParameterizedType ) { + if ( parameters != null ) { + ( (ParameterizedType) typeInstance ).setParameterValues( parameters ); + } + } if ( typeInstance instanceof UserType ) { return new CustomType( diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/BasicValue.java b/hibernate-core/src/main/java/org/hibernate/mapping/BasicValue.java index b0a0d7c7ff..58914e0e76 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/BasicValue.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/BasicValue.java @@ -8,10 +8,8 @@ package org.hibernate.mapping; import java.util.Map; import java.util.Properties; +import java.util.function.Consumer; import java.util.function.Function; -import jakarta.persistence.AttributeConverter; -import jakarta.persistence.EnumType; -import jakarta.persistence.TemporalType; import org.hibernate.MappingException; import org.hibernate.boot.model.TypeDefinition; @@ -42,15 +40,17 @@ import org.hibernate.type.BasicType; import org.hibernate.type.ConvertedBasicType; import org.hibernate.type.Type; import org.hibernate.type.descriptor.java.BasicJavaDescriptor; -import org.hibernate.type.descriptor.java.EnumJavaTypeDescriptor; import org.hibernate.type.descriptor.java.JavaTypeDescriptor; import org.hibernate.type.descriptor.java.MutabilityPlan; -import org.hibernate.type.descriptor.java.TemporalJavaTypeDescriptor; import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptor; import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators; import org.hibernate.type.spi.TypeConfiguration; import org.hibernate.usertype.DynamicParameterizedType; +import jakarta.persistence.AttributeConverter; +import jakarta.persistence.EnumType; +import jakarta.persistence.TemporalType; + /** * @author Steve Ebersole */ @@ -295,6 +295,7 @@ public class BasicValue extends SimpleValue implements JdbcTypeDescriptorIndicat explicitMutabilityPlanAccess, getAttributeConverterDescriptor(), typeParameters, + this::setTypeParameters, this, typeConfiguration, getBuildingContext() @@ -434,6 +435,7 @@ public class BasicValue extends SimpleValue implements JdbcTypeDescriptorIndicat Function explicitMutabilityPlanAccess, ConverterDescriptor converterDescriptor, Map localTypeParams, + Consumer combinedParameterConsumer, JdbcTypeDescriptorIndicators stdIndicators, TypeConfiguration typeConfiguration, MetadataBuildingContext context) { @@ -502,7 +504,7 @@ public class BasicValue extends SimpleValue implements JdbcTypeDescriptorIndicat // see if it is a named TypeDefinition final TypeDefinition typeDefinition = context.getTypeDefinitionRegistry().resolve( name ); if ( typeDefinition != null ) { - return typeDefinition.resolve( + final Resolution resolution = typeDefinition.resolve( localTypeParams, explicitMutabilityPlanAccess != null ? explicitMutabilityPlanAccess.apply( typeConfiguration ) @@ -510,6 +512,8 @@ public class BasicValue extends SimpleValue implements JdbcTypeDescriptorIndicat context, stdIndicators ); + combinedParameterConsumer.accept( resolution.getCombinedTypeParameters() ); + return resolution; } @@ -636,6 +640,14 @@ public class BasicValue extends SimpleValue implements JdbcTypeDescriptorIndicat */ BasicType getLegacyResolvedBasicType(); + /** + * Get the collection of type-parameters collected both locally as well + * as from the applied type-def, if one + */ + default Properties getCombinedTypeParameters() { + return null; + } + JdbcMapping getJdbcMapping(); /**