HHH-14820 - Customized EnumType not working with hbm mapping in Hibernate 6

This commit is contained in:
Steve Ebersole 2021-09-30 14:57:30 -05:00
parent c799f85801
commit ab2957d89f
4 changed files with 69 additions and 33 deletions

View File

@ -14,6 +14,7 @@ import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Properties; import java.util.Properties;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.function.Supplier; import java.util.function.Supplier;
import org.hibernate.boot.model.process.internal.UserTypeResolution; import org.hibernate.boot.model.process.internal.UserTypeResolution;
@ -162,25 +163,27 @@ public class TypeDefinition implements Serializable {
( (TypeConfigurationAware) typeInstance ).setTypeConfiguration( typeConfiguration ); ( (TypeConfigurationAware) typeInstance ).setTypeConfiguration( typeConfiguration );
} }
injectParameters( final Properties combinedTypeParameters;
typeInstance,
() -> {
if ( CollectionHelper.isNotEmpty( usageSiteProperties ) ) { if ( CollectionHelper.isNotEmpty( usageSiteProperties ) ) {
final Properties properties = new Properties( parameters ); combinedTypeParameters = new Properties( parameters );
properties.putAll( usageSiteProperties ); combinedTypeParameters.putAll( usageSiteProperties );
return properties;
} }
else { else {
return parameters; combinedTypeParameters = parameters;
}
if ( typeInstance instanceof ParameterizedType ) {
if ( combinedTypeParameters != null ) {
( (ParameterizedType) typeInstance ).setParameterValues( combinedTypeParameters );
} }
} }
);
if ( typeInstance instanceof UserType ) { if ( typeInstance instanceof UserType ) {
final UserType userType = (UserType) typeInstance; final UserType userType = (UserType) typeInstance;
final CustomType customType = new CustomType( userType, typeConfiguration ); final CustomType customType = new CustomType( userType, typeConfiguration );
return new UserTypeResolution( customType, null ); return new UserTypeResolution( customType, null, combinedTypeParameters );
} }
if ( typeInstance instanceof BasicType ) { if ( typeInstance instanceof BasicType ) {
@ -196,6 +199,11 @@ public class TypeDefinition implements Serializable {
return resolvedBasicType; return resolvedBasicType;
} }
@Override
public Properties getCombinedTypeParameters() {
return combinedTypeParameters;
}
@Override @Override
public JavaTypeDescriptor<Object> getDomainJavaDescriptor() { public JavaTypeDescriptor<Object> getDomainJavaDescriptor() {
return resolvedBasicType.getMappedJavaTypeDescriptor(); return resolvedBasicType.getMappedJavaTypeDescriptor();
@ -283,15 +291,6 @@ public class TypeDefinition implements Serializable {
); );
} }
public static void injectParameters(Object customType, Supplier<Properties> parameterSupplier) {
if ( customType instanceof ParameterizedType ) {
final Properties parameterValues = parameterSupplier.get();
if ( parameterValues != null ) {
( (ParameterizedType) customType ).setParameterValues( parameterValues );
}
}
}
public static BasicValue.Resolution<?> createLocalResolution( public static BasicValue.Resolution<?> createLocalResolution(
String name, String name,
Class typeImplementorClass, Class typeImplementorClass,

View File

@ -6,6 +6,8 @@
*/ */
package org.hibernate.boot.model.process.internal; package org.hibernate.boot.model.process.internal;
import java.util.Properties;
import org.hibernate.mapping.BasicValue; import org.hibernate.mapping.BasicValue;
import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter; import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
@ -22,10 +24,14 @@ public class UserTypeResolution implements BasicValue.Resolution {
private final CustomType userTypeAdapter; private final CustomType userTypeAdapter;
private final MutabilityPlan mutabilityPlan; private final MutabilityPlan mutabilityPlan;
private final Properties combinedTypeParameters;
public UserTypeResolution( public UserTypeResolution(
CustomType userTypeAdapter, CustomType userTypeAdapter,
MutabilityPlan explicitMutabilityPlan) { MutabilityPlan explicitMutabilityPlan,
Properties combinedTypeParameters) {
this.userTypeAdapter = userTypeAdapter; this.userTypeAdapter = userTypeAdapter;
this.combinedTypeParameters = combinedTypeParameters;
this.mutabilityPlan = explicitMutabilityPlan != null this.mutabilityPlan = explicitMutabilityPlan != null
? explicitMutabilityPlan ? explicitMutabilityPlan
: new UserTypeMutabilityPlanAdapter( userTypeAdapter.getUserType() ); : new UserTypeMutabilityPlanAdapter( userTypeAdapter.getUserType() );
@ -61,6 +67,11 @@ public class UserTypeResolution implements BasicValue.Resolution {
return userTypeAdapter; return userTypeAdapter;
} }
@Override
public Properties getCombinedTypeParameters() {
return combinedTypeParameters;
}
@Override @Override
public JdbcMapping getJdbcMapping() { public JdbcMapping getJdbcMapping() {
return userTypeAdapter; return userTypeAdapter;

View File

@ -159,6 +159,7 @@ import org.hibernate.type.DiscriminatorType;
import org.hibernate.type.ForeignKeyDirection; import org.hibernate.type.ForeignKeyDirection;
import org.hibernate.type.NClobType; import org.hibernate.type.NClobType;
import org.hibernate.type.StandardBasicTypes; import org.hibernate.type.StandardBasicTypes;
import org.hibernate.usertype.ParameterizedType;
import org.hibernate.usertype.UserType; import org.hibernate.usertype.UserType;
import static org.hibernate.internal.util.collections.CollectionHelper.isEmpty; import static org.hibernate.internal.util.collections.CollectionHelper.isEmpty;
@ -2400,7 +2401,8 @@ public class ModelBinder {
discriminatorTypeName = discriminatorTypeResolution.typeName; discriminatorTypeName = discriminatorTypeResolution.typeName;
discriminatorType = resolveExplicitlyNamedAnyDiscriminatorType( discriminatorType = resolveExplicitlyNamedAnyDiscriminatorType(
discriminatorTypeResolution.typeName, discriminatorTypeResolution.typeName,
discriminatorTypeResolution.parameters discriminatorTypeResolution.parameters,
anyBinding.getMetaMapping()
); );
} }
else { 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(); final BootstrapContext bootstrapContext = metadataBuildingContext.getBootstrapContext();
if ( isEmpty( parameters ) ) { if ( isEmpty( parameters ) ) {
@ -2480,6 +2485,10 @@ public class ModelBinder {
bootstrapContext.getTypeConfiguration().getCurrentBaseSqlTypeIndicators() bootstrapContext.getTypeConfiguration().getCurrentBaseSqlTypeIndicators()
); );
if ( resolution.getCombinedTypeParameters() != null ) {
discriminatorMapping.setTypeParameters( resolution.getCombinedTypeParameters() );
}
return (DiscriminatorType<?>) resolution.getLegacyResolvedBasicType(); return (DiscriminatorType<?>) resolution.getLegacyResolvedBasicType();
} }
@ -2496,7 +2505,12 @@ public class ModelBinder {
.getService( ManagedBeanRegistry.class ); .getService( ManagedBeanRegistry.class );
final ManagedBean<?> bean = beanRegistry.getBean( beanName, typeJavaType ); final ManagedBean<?> bean = beanRegistry.getBean( beanName, typeJavaType );
final Object typeInstance = bean.getBeanInstance(); final Object typeInstance = bean.getBeanInstance();
TypeDefinition.injectParameters( typeInstance, () -> parameters );
if ( typeInstance instanceof ParameterizedType ) {
if ( parameters != null ) {
( (ParameterizedType) typeInstance ).setParameterValues( parameters );
}
}
if ( typeInstance instanceof UserType ) { if ( typeInstance instanceof UserType ) {
return new CustomType( return new CustomType(

View File

@ -8,10 +8,8 @@ package org.hibernate.mapping;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
import jakarta.persistence.AttributeConverter;
import jakarta.persistence.EnumType;
import jakarta.persistence.TemporalType;
import org.hibernate.MappingException; import org.hibernate.MappingException;
import org.hibernate.boot.model.TypeDefinition; import org.hibernate.boot.model.TypeDefinition;
@ -42,15 +40,17 @@ import org.hibernate.type.BasicType;
import org.hibernate.type.ConvertedBasicType; import org.hibernate.type.ConvertedBasicType;
import org.hibernate.type.Type; import org.hibernate.type.Type;
import org.hibernate.type.descriptor.java.BasicJavaDescriptor; 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.JavaTypeDescriptor;
import org.hibernate.type.descriptor.java.MutabilityPlan; 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.JdbcTypeDescriptor;
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators; import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
import org.hibernate.type.spi.TypeConfiguration; import org.hibernate.type.spi.TypeConfiguration;
import org.hibernate.usertype.DynamicParameterizedType; import org.hibernate.usertype.DynamicParameterizedType;
import jakarta.persistence.AttributeConverter;
import jakarta.persistence.EnumType;
import jakarta.persistence.TemporalType;
/** /**
* @author Steve Ebersole * @author Steve Ebersole
*/ */
@ -295,6 +295,7 @@ public class BasicValue extends SimpleValue implements JdbcTypeDescriptorIndicat
explicitMutabilityPlanAccess, explicitMutabilityPlanAccess,
getAttributeConverterDescriptor(), getAttributeConverterDescriptor(),
typeParameters, typeParameters,
this::setTypeParameters,
this, this,
typeConfiguration, typeConfiguration,
getBuildingContext() getBuildingContext()
@ -434,6 +435,7 @@ public class BasicValue extends SimpleValue implements JdbcTypeDescriptorIndicat
Function<TypeConfiguration, MutabilityPlan> explicitMutabilityPlanAccess, Function<TypeConfiguration, MutabilityPlan> explicitMutabilityPlanAccess,
ConverterDescriptor converterDescriptor, ConverterDescriptor converterDescriptor,
Map localTypeParams, Map localTypeParams,
Consumer<Properties> combinedParameterConsumer,
JdbcTypeDescriptorIndicators stdIndicators, JdbcTypeDescriptorIndicators stdIndicators,
TypeConfiguration typeConfiguration, TypeConfiguration typeConfiguration,
MetadataBuildingContext context) { MetadataBuildingContext context) {
@ -502,7 +504,7 @@ public class BasicValue extends SimpleValue implements JdbcTypeDescriptorIndicat
// see if it is a named TypeDefinition // see if it is a named TypeDefinition
final TypeDefinition typeDefinition = context.getTypeDefinitionRegistry().resolve( name ); final TypeDefinition typeDefinition = context.getTypeDefinitionRegistry().resolve( name );
if ( typeDefinition != null ) { if ( typeDefinition != null ) {
return typeDefinition.resolve( final Resolution<?> resolution = typeDefinition.resolve(
localTypeParams, localTypeParams,
explicitMutabilityPlanAccess != null explicitMutabilityPlanAccess != null
? explicitMutabilityPlanAccess.apply( typeConfiguration ) ? explicitMutabilityPlanAccess.apply( typeConfiguration )
@ -510,6 +512,8 @@ public class BasicValue extends SimpleValue implements JdbcTypeDescriptorIndicat
context, context,
stdIndicators stdIndicators
); );
combinedParameterConsumer.accept( resolution.getCombinedTypeParameters() );
return resolution;
} }
@ -636,6 +640,14 @@ public class BasicValue extends SimpleValue implements JdbcTypeDescriptorIndicat
*/ */
BasicType<J> getLegacyResolvedBasicType(); BasicType<J> 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(); JdbcMapping getJdbcMapping();
/** /**