fix problem where Hibernate refused to instantiate non-public UserType

also:

- clean up some code with respect to generic typing
- improve some exception reporting
This commit is contained in:
Gavin King 2023-07-26 13:44:15 +02:00
parent 0725022d79
commit 9add83ec92
12 changed files with 321 additions and 304 deletions

View File

@ -15,7 +15,7 @@ public class InstantiationException extends HibernateException {
private final Class<?> clazz; private final Class<?> clazz;
/** /**
* Constructs a {@code InstantiationException}. * Constructs an {@code InstantiationException}.
* *
* @param message A message explaining the exception condition * @param message A message explaining the exception condition
* @param clazz The Class we are attempting to instantiate * @param clazz The Class we are attempting to instantiate

View File

@ -6,15 +6,16 @@
*/ */
package org.hibernate.boot.model; package org.hibernate.boot.model;
import org.hibernate.InstantiationException;
import org.hibernate.Internal;
import org.hibernate.engine.config.spi.ConfigurationService;
import org.hibernate.resource.beans.spi.BeanInstanceProducer;
import org.hibernate.type.spi.TypeBootstrapContext;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.util.Map; import java.util.Map;
import org.hibernate.Internal; import static org.hibernate.internal.util.ReflectHelper.getConstructor;
import org.hibernate.MappingException;
import org.hibernate.engine.config.spi.ConfigurationService;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.resource.beans.spi.BeanInstanceProducer;
import org.hibernate.type.spi.TypeBootstrapContext;
/** /**
* {@link BeanInstanceProducer} implementation for building beans related to custom types. * {@link BeanInstanceProducer} implementation for building beans related to custom types.
@ -31,20 +32,29 @@ public TypeBeanInstanceProducer(ConfigurationService configurationService) {
@Override @Override
public <B> B produceBeanInstance(Class<B> beanType) { public <B> B produceBeanInstance(Class<B> beanType) {
try { final Constructor<B> bootstrapContextAwareConstructor =
final Constructor<B> bootstrapContextAwareTypeConstructor = ReflectHelper.getConstructor( getConstructor( beanType, TypeBootstrapContext.class );
beanType, if ( bootstrapContextAwareConstructor != null ) {
TypeBootstrapContext.class try {
); return bootstrapContextAwareConstructor.newInstance( this );
if ( bootstrapContextAwareTypeConstructor != null ) {
return bootstrapContextAwareTypeConstructor.newInstance( this );
} }
else { catch ( Exception e ) {
return beanType.newInstance(); throw new InstantiationException( "Could not instantiate type", beanType, e );
} }
} }
catch ( Exception e ) { else {
throw new MappingException( "Could not instantiate Type: " + beanType.getName(), e ); final Constructor<B> constructor = getConstructor( beanType );
if ( constructor != null ) {
try {
return constructor.newInstance();
}
catch ( Exception e ) {
throw new InstantiationException( "Could not instantiate type", beanType, e );
}
}
else {
throw new InstantiationException( "No appropriate constructor for type", beanType );
}
} }
} }

View File

@ -15,7 +15,6 @@
import java.util.Properties; import java.util.Properties;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import org.hibernate.boot.model.process.internal.InferredBasicValueResolver;
import org.hibernate.boot.model.process.internal.UserTypeResolution; import org.hibernate.boot.model.process.internal.UserTypeResolution;
import org.hibernate.boot.registry.StandardServiceRegistry; import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.spi.BootstrapContext; import org.hibernate.boot.spi.BootstrapContext;
@ -42,6 +41,7 @@
import org.hibernate.type.spi.TypeConfigurationAware; import org.hibernate.type.spi.TypeConfigurationAware;
import org.hibernate.usertype.UserType; import org.hibernate.usertype.UserType;
import static org.hibernate.boot.model.process.internal.InferredBasicValueResolver.resolveSqlTypeIndicators;
import static org.hibernate.mapping.MappingHelper.injectParameters; import static org.hibernate.mapping.MappingHelper.injectParameters;
/** /**
@ -131,9 +131,9 @@ private BasicValue.Resolution<?> createResolution(
); );
} }
private static BasicValue.Resolution<?> createResolution( private static <T> BasicValue.Resolution<T> createResolution(
String name, String name,
Class<?> typeImplementorClass, Class<T> typeImplementorClass,
Map<?,?> parameters, Map<?,?> parameters,
Map<?,?> usageSiteProperties, Map<?,?> usageSiteProperties,
JdbcTypeIndicators indicators, JdbcTypeIndicators indicators,
@ -141,16 +141,18 @@ private static BasicValue.Resolution<?> createResolution(
final BootstrapContext bootstrapContext = context.getBootstrapContext(); final BootstrapContext bootstrapContext = context.getBootstrapContext();
final TypeConfiguration typeConfiguration = bootstrapContext.getTypeConfiguration(); final TypeConfiguration typeConfiguration = bootstrapContext.getTypeConfiguration();
final BeanInstanceProducer instanceProducer = bootstrapContext.getCustomTypeProducer(); final BeanInstanceProducer instanceProducer = bootstrapContext.getCustomTypeProducer();
final boolean isKnownType = Type.class.isAssignableFrom( typeImplementorClass ) final boolean isKnownType =
Type.class.isAssignableFrom( typeImplementorClass )
|| UserType.class.isAssignableFrom( typeImplementorClass ); || UserType.class.isAssignableFrom( typeImplementorClass );
// support for AttributeConverter would be nice too // support for AttributeConverter would be nice too
if ( isKnownType ) { if ( isKnownType ) {
final Object typeInstance = instantiateType( bootstrapContext.getServiceRegistry(), final T typeInstance = instantiateType( bootstrapContext.getServiceRegistry(),
context.getBuildingOptions(), name, typeImplementorClass, instanceProducer ); context.getBuildingOptions(), name, typeImplementorClass, instanceProducer );
if ( typeInstance instanceof TypeConfigurationAware ) { if ( typeInstance instanceof TypeConfigurationAware ) {
( (TypeConfigurationAware) typeInstance ).setTypeConfiguration( typeConfiguration ); final TypeConfigurationAware configurationAware = (TypeConfigurationAware) typeInstance;
configurationAware.setTypeConfiguration( typeConfiguration );
} }
final Properties combinedTypeParameters = new Properties(); final Properties combinedTypeParameters = new Properties();
@ -164,22 +166,23 @@ private static BasicValue.Resolution<?> createResolution(
injectParameters( typeInstance, combinedTypeParameters ); injectParameters( typeInstance, combinedTypeParameters );
if ( typeInstance instanceof UserType ) { if ( typeInstance instanceof UserType ) {
final UserType<?> userType = (UserType<?>) typeInstance; @SuppressWarnings("unchecked")
final CustomType<?> customType = new CustomType<>( userType, typeConfiguration ); final UserType<T> userType = (UserType<T>) typeInstance;
final CustomType<T> customType = new CustomType<>( userType, typeConfiguration );
return new UserTypeResolution( customType, null, combinedTypeParameters ); return new UserTypeResolution<>( customType, null, combinedTypeParameters );
} }
if ( typeInstance instanceof BasicType ) { if ( typeInstance instanceof BasicType ) {
final BasicType<?> resolvedBasicType = (BasicType<?>) typeInstance; @SuppressWarnings("unchecked")
final BasicType<T> resolvedBasicType = (BasicType<T>) typeInstance;
return new BasicValue.Resolution<>() { return new BasicValue.Resolution<>() {
@Override @Override
public JdbcMapping getJdbcMapping() { public JdbcMapping getJdbcMapping() {
return resolvedBasicType; return resolvedBasicType;
} }
@Override @SuppressWarnings({"rawtypes", "unchecked"}) @Override
public BasicType getLegacyResolvedBasicType() { public BasicType<T> getLegacyResolvedBasicType() {
return resolvedBasicType; return resolvedBasicType;
} }
@ -188,8 +191,8 @@ public Properties getCombinedTypeParameters() {
return combinedTypeParameters; return combinedTypeParameters;
} }
@Override @SuppressWarnings({"rawtypes", "unchecked"}) @Override
public JavaType getDomainJavaType() { public JavaType<T> getDomainJavaType() {
return resolvedBasicType.getMappedJavaType(); return resolvedBasicType.getMappedJavaType();
} }
@ -204,12 +207,12 @@ public JdbcType getJdbcType() {
} }
@Override @Override
public BasicValueConverter getValueConverter() { public BasicValueConverter<T,?> getValueConverter() {
return resolvedBasicType.getValueConverter(); return resolvedBasicType.getValueConverter();
} }
@Override @SuppressWarnings({"rawtypes", "unchecked"}) @Override
public MutabilityPlan getMutabilityPlan() { public MutabilityPlan<T> getMutabilityPlan() {
// a TypeDefinition does not explicitly provide a MutabilityPlan (yet?) // a TypeDefinition does not explicitly provide a MutabilityPlan (yet?)
return resolvedBasicType.isMutable() return resolvedBasicType.isMutable()
? getDomainJavaType().getMutabilityPlan() ? getDomainJavaType().getMutabilityPlan()
@ -220,37 +223,35 @@ public MutabilityPlan getMutabilityPlan() {
} }
// Series of backward compatible special cases // Series of backward compatible special cases
return resolveLegacyCases( typeImplementorClass, indicators, typeConfiguration );
if ( Serializable.class.isAssignableFrom( typeImplementorClass ) ) {
@SuppressWarnings({"rawtypes", "unchecked"})
final SerializableType legacyType = new SerializableType( typeImplementorClass );
return createBasicTypeResolution( legacyType, typeImplementorClass, indicators, typeConfiguration );
}
if ( typeImplementorClass.isInterface() ) {
return createBasicTypeResolution( new JavaObjectType(), typeImplementorClass, indicators, typeConfiguration );
}
throw new IllegalArgumentException(
"Named type [" + typeImplementorClass + "] did not implement BasicType nor UserType"
);
} }
private static BasicValue.Resolution<Object> createBasicTypeResolution( private static <T> BasicValue.Resolution<T> resolveLegacyCases(
BasicType<?> type, Class<T> typeImplementorClass, JdbcTypeIndicators indicators, TypeConfiguration typeConfiguration) {
Class<?> typeImplementorClass, final BasicType<T> legacyType;
if ( Serializable.class.isAssignableFrom( typeImplementorClass ) ) {
legacyType = new SerializableType( typeImplementorClass );
}
else if ( typeImplementorClass.isInterface() ) {
legacyType = (BasicType<T>) new JavaObjectType();
}
else {
throw new IllegalArgumentException( "Named type [" + typeImplementorClass
+ "] did not implement BasicType nor UserType" );
}
return createBasicTypeResolution( legacyType, typeImplementorClass, indicators, typeConfiguration );
}
private static <T> BasicValue.Resolution<T> createBasicTypeResolution(
BasicType<T> type,
Class<? extends T> typeImplementorClass,
JdbcTypeIndicators indicators, JdbcTypeIndicators indicators,
TypeConfiguration typeConfiguration TypeConfiguration typeConfiguration) {
) { final JavaType<T> jtd = typeConfiguration.getJavaTypeRegistry().resolveDescriptor( typeImplementorClass );
final JavaType<Serializable> jtd = typeConfiguration
.getJavaTypeRegistry()
.resolveDescriptor( typeImplementorClass );
final JdbcType jdbcType = typeConfiguration.getJdbcTypeRegistry().getDescriptor( Types.VARBINARY ); final JdbcType jdbcType = typeConfiguration.getJdbcTypeRegistry().getDescriptor( Types.VARBINARY );
final BasicType<Serializable> resolved = InferredBasicValueResolver.resolveSqlTypeIndicators( final BasicType<T> basicType = typeConfiguration.getBasicTypeRegistry().resolve( jtd, jdbcType );
indicators, final BasicType<T> resolved = resolveSqlTypeIndicators( indicators, basicType, jtd );
typeConfiguration.getBasicTypeRegistry().resolve( jtd, jdbcType ),
jtd
);
return new BasicValue.Resolution<>() { return new BasicValue.Resolution<>() {
@Override @Override
@ -259,14 +260,12 @@ public JdbcMapping getJdbcMapping() {
} }
@Override @Override
@SuppressWarnings({ "rawtypes", "unchecked" }) public BasicType<T> getLegacyResolvedBasicType() {
public BasicType getLegacyResolvedBasicType() {
return type; return type;
} }
@Override @Override
@SuppressWarnings({ "rawtypes", "unchecked" }) public JavaType<T> getDomainJavaType() {
public JavaType getDomainJavaType() {
return resolved.getMappedJavaType(); return resolved.getMappedJavaType();
} }
@ -281,13 +280,12 @@ public JdbcType getJdbcType() {
} }
@Override @Override
public BasicValueConverter getValueConverter() { public BasicValueConverter<T,?> getValueConverter() {
return resolved.getValueConverter(); return resolved.getValueConverter();
} }
@Override @Override
@SuppressWarnings({ "rawtypes", "unchecked" }) public MutabilityPlan<T> getMutabilityPlan() {
public MutabilityPlan getMutabilityPlan() {
// a TypeDefinition does not explicitly provide a MutabilityPlan (yet?) // a TypeDefinition does not explicitly provide a MutabilityPlan (yet?)
return resolved.isMutable() return resolved.isMutable()
? getDomainJavaType().getMutabilityPlan() ? getDomainJavaType().getMutabilityPlan()
@ -296,11 +294,11 @@ public MutabilityPlan getMutabilityPlan() {
}; };
} }
private static Object instantiateType( private static <T> T instantiateType(
StandardServiceRegistry serviceRegistry, StandardServiceRegistry serviceRegistry,
MetadataBuildingOptions buildingOptions, MetadataBuildingOptions buildingOptions,
String name, String name,
Class<?> typeImplementorClass, Class<T> typeImplementorClass,
BeanInstanceProducer instanceProducer) { BeanInstanceProducer instanceProducer) {
if ( buildingOptions.disallowExtensionsInCdi() ) { if ( buildingOptions.disallowExtensionsInCdi() ) {
return name != null return name != null
@ -308,8 +306,8 @@ private static Object instantiateType(
: instanceProducer.produceBeanInstance( typeImplementorClass ); : instanceProducer.produceBeanInstance( typeImplementorClass );
} }
else { else {
final ManagedBeanRegistry beanRegistry = serviceRegistry.getService( ManagedBeanRegistry.class ); final ManagedBeanRegistry beanRegistry = serviceRegistry.requireService( ManagedBeanRegistry.class );
final ManagedBean<?> typeBean = name != null final ManagedBean<T> typeBean = name != null
? beanRegistry.getBean( name, typeImplementorClass, instanceProducer ) ? beanRegistry.getBean( name, typeImplementorClass, instanceProducer )
: beanRegistry.getBean( typeImplementorClass, instanceProducer ); : beanRegistry.getBean( typeImplementorClass, instanceProducer );
return typeBean.getBeanInstance(); return typeBean.getBeanInstance();

View File

@ -48,6 +48,7 @@
import org.hibernate.boot.model.convert.spi.RegisteredConversion; import org.hibernate.boot.model.convert.spi.RegisteredConversion;
import org.hibernate.boot.registry.StandardServiceRegistry; import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.boot.spi.BootstrapContext;
import org.hibernate.boot.spi.InFlightMetadataCollector; import org.hibernate.boot.spi.InFlightMetadataCollector;
import org.hibernate.boot.spi.MetadataBuildingContext; import org.hibernate.boot.spi.MetadataBuildingContext;
import org.hibernate.dialect.Dialect; import org.hibernate.dialect.Dialect;
@ -601,6 +602,8 @@ private static void bindUserTypeRegistrations(
private static void handleUserTypeRegistration( private static void handleUserTypeRegistration(
MetadataBuildingContext context, MetadataBuildingContext context,
TypeRegistration compositeTypeRegistration) { TypeRegistration compositeTypeRegistration) {
// TODO: check that the two classes agree, i.e. that
// the user type knows how to handle the type
context.getMetadataCollector().registerUserType( context.getMetadataCollector().registerUserType(
compositeTypeRegistration.basicClass(), compositeTypeRegistration.basicClass(),
compositeTypeRegistration.userType() compositeTypeRegistration.userType()
@ -610,6 +613,8 @@ private static void handleUserTypeRegistration(
private static void handleCompositeUserTypeRegistration( private static void handleCompositeUserTypeRegistration(
MetadataBuildingContext context, MetadataBuildingContext context,
CompositeTypeRegistration compositeTypeRegistration) { CompositeTypeRegistration compositeTypeRegistration) {
// TODO: check that the two classes agree, i.e. that
// the user type knows how to handle the type
context.getMetadataCollector().registerCompositeUserType( context.getMetadataCollector().registerCompositeUserType(
compositeTypeRegistration.embeddableClass(), compositeTypeRegistration.embeddableClass(),
compositeTypeRegistration.userType() compositeTypeRegistration.userType()
@ -755,25 +760,21 @@ public Dialect getDialect() {
} }
private static JdbcMapping resolveUserType(Class<UserType<?>> userTypeClass, MetadataBuildingContext context) { private static JdbcMapping resolveUserType(Class<UserType<?>> userTypeClass, MetadataBuildingContext context) {
final UserType<?> userType; final UserType<?> userType = context.getBuildingOptions().disallowExtensionsInCdi()
if ( context.getBuildingOptions().disallowExtensionsInCdi() ) { ? FallbackBeanInstanceProducer.INSTANCE.produceBeanInstance( userTypeClass )
userType = FallbackBeanInstanceProducer.INSTANCE.produceBeanInstance( userTypeClass ); : context.getBootstrapContext().getServiceRegistry()
} .requireService( ManagedBeanRegistry.class )
else { .getBean( userTypeClass ).getBeanInstance();
final StandardServiceRegistry serviceRegistry = context.getBootstrapContext().getServiceRegistry();
final ManagedBeanRegistry beanRegistry = serviceRegistry.getService( ManagedBeanRegistry.class );
userType = beanRegistry.getBean( userTypeClass ).getBeanInstance();
}
return new CustomType<>( userType, context.getBootstrapContext().getTypeConfiguration() ); return new CustomType<>( userType, context.getBootstrapContext().getTypeConfiguration() );
} }
private static JdbcMapping resolveAttributeConverter(Class<AttributeConverter<?, ?>> type, MetadataBuildingContext context) { private static JdbcMapping resolveAttributeConverter(Class<AttributeConverter<?, ?>> type, MetadataBuildingContext context) {
final StandardServiceRegistry serviceRegistry = context.getBootstrapContext().getServiceRegistry(); final BootstrapContext bootstrapContext = context.getBootstrapContext();
final ManagedBeanRegistry beanRegistry = serviceRegistry.getService( ManagedBeanRegistry.class ); final ManagedBeanRegistry beanRegistry =
bootstrapContext.getServiceRegistry().requireService( ManagedBeanRegistry.class );
final ManagedBean<AttributeConverter<?, ?>> bean = beanRegistry.getBean( type ); final ManagedBean<AttributeConverter<?, ?>> bean = beanRegistry.getBean( type );
final TypeConfiguration typeConfiguration = context.getBootstrapContext().getTypeConfiguration(); final TypeConfiguration typeConfiguration = bootstrapContext.getTypeConfiguration();
final JavaTypeRegistry jtdRegistry = typeConfiguration.getJavaTypeRegistry(); final JavaTypeRegistry jtdRegistry = typeConfiguration.getJavaTypeRegistry();
final JavaType<? extends AttributeConverter<?,?>> converterJtd = jtdRegistry.resolveDescriptor( bean.getBeanClass() ); final JavaType<? extends AttributeConverter<?,?>> converterJtd = jtdRegistry.resolveDescriptor( bean.getBeanClass() );

View File

@ -20,9 +20,9 @@
/** /**
* @author Steve Ebersole * @author Steve Ebersole
*/ */
public class UserTypeResolution implements BasicValue.Resolution { public class UserTypeResolution<T> implements BasicValue.Resolution<T> {
private final CustomType<?> userTypeAdapter; private final CustomType<T> userTypeAdapter;
private final MutabilityPlan<?> mutabilityPlan; private final MutabilityPlan<T> mutabilityPlan;
/** /**
* We need this for the way envers interprets the boot-model * We need this for the way envers interprets the boot-model
@ -31,8 +31,8 @@ public class UserTypeResolution implements BasicValue.Resolution {
private final Properties combinedTypeParameters; private final Properties combinedTypeParameters;
public UserTypeResolution( public UserTypeResolution(
CustomType<?> userTypeAdapter, CustomType<T> userTypeAdapter,
MutabilityPlan<?> explicitMutabilityPlan, MutabilityPlan<T> explicitMutabilityPlan,
Properties combinedTypeParameters) { Properties combinedTypeParameters) {
this.userTypeAdapter = userTypeAdapter; this.userTypeAdapter = userTypeAdapter;
this.combinedTypeParameters = combinedTypeParameters; this.combinedTypeParameters = combinedTypeParameters;
@ -42,7 +42,7 @@ public UserTypeResolution(
} }
@Override @Override
public JavaType<?> getDomainJavaType() { public JavaType<T> getDomainJavaType() {
return userTypeAdapter.getJavaTypeDescriptor(); return userTypeAdapter.getJavaTypeDescriptor();
} }
@ -57,7 +57,7 @@ public JdbcType getJdbcType() {
} }
@Override @Override
public BasicValueConverter getValueConverter() { public BasicValueConverter<T,?> getValueConverter() {
// Even though we could expose the value converter of the user type here, // Even though we could expose the value converter of the user type here,
// we can not do it, as the conversion is done behind the scenes in the binder/extractor, // we can not do it, as the conversion is done behind the scenes in the binder/extractor,
// whereas the converter returned here would, AFAIU, be used to construct a converted attribute mapping // whereas the converter returned here would, AFAIU, be used to construct a converted attribute mapping
@ -65,12 +65,12 @@ public BasicValueConverter getValueConverter() {
} }
@Override @Override
public MutabilityPlan getMutabilityPlan() { public MutabilityPlan<T> getMutabilityPlan() {
return mutabilityPlan; return mutabilityPlan;
} }
@Override @Override
public BasicType getLegacyResolvedBasicType() { public BasicType<T> getLegacyResolvedBasicType() {
return userTypeAdapter; return userTypeAdapter;
} }

View File

@ -147,7 +147,6 @@
import org.hibernate.mapping.UniqueKey; import org.hibernate.mapping.UniqueKey;
import org.hibernate.mapping.Value; import org.hibernate.mapping.Value;
import org.hibernate.resource.beans.internal.FallbackBeanInstanceProducer; import org.hibernate.resource.beans.internal.FallbackBeanInstanceProducer;
import org.hibernate.resource.beans.spi.ManagedBean;
import org.hibernate.resource.beans.spi.ManagedBeanRegistry; import org.hibernate.resource.beans.spi.ManagedBeanRegistry;
import org.hibernate.spi.NavigablePath; import org.hibernate.spi.NavigablePath;
import org.hibernate.tuple.GenerationTiming; import org.hibernate.tuple.GenerationTiming;
@ -156,6 +155,7 @@
import org.hibernate.type.CustomType; import org.hibernate.type.CustomType;
import org.hibernate.type.ForeignKeyDirection; import org.hibernate.type.ForeignKeyDirection;
import org.hibernate.type.StandardBasicTypes; import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.spi.TypeConfiguration;
import org.hibernate.usertype.CompositeUserType; import org.hibernate.usertype.CompositeUserType;
import org.hibernate.usertype.ParameterizedType; import org.hibernate.usertype.ParameterizedType;
import org.hibernate.usertype.UserType; import org.hibernate.usertype.UserType;
@ -2349,13 +2349,11 @@ private BasicType<?> resolveExplicitlyNamedAnyDiscriminatorType(
Map<String,String> parameters, Map<String,String> parameters,
Any.MetaValue discriminatorMapping) { Any.MetaValue discriminatorMapping) {
final BootstrapContext bootstrapContext = metadataBuildingContext.getBootstrapContext(); final BootstrapContext bootstrapContext = metadataBuildingContext.getBootstrapContext();
final TypeConfiguration typeConfiguration = bootstrapContext.getTypeConfiguration();
if ( isEmpty( parameters ) ) { if ( isEmpty( parameters ) ) {
// can use a standard one // can use a standard one
final BasicType<?> basicTypeByName = bootstrapContext final BasicType<?> basicTypeByName = typeConfiguration.getBasicTypeRegistry().getRegisteredType( typeName );
.getTypeConfiguration()
.getBasicTypeRegistry()
.getRegisteredType( typeName );
if ( basicTypeByName != null ) { if ( basicTypeByName != null ) {
return basicTypeByName; return basicTypeByName;
} }
@ -2368,7 +2366,7 @@ private BasicType<?> resolveExplicitlyNamedAnyDiscriminatorType(
parameters, parameters,
null, null,
metadataBuildingContext, metadataBuildingContext,
bootstrapContext.getTypeConfiguration().getCurrentBaseSqlTypeIndicators() typeConfiguration.getCurrentBaseSqlTypeIndicators()
); );
if ( resolution.getCombinedTypeParameters() != null ) { if ( resolution.getCombinedTypeParameters() != null ) {
@ -2377,56 +2375,50 @@ private BasicType<?> resolveExplicitlyNamedAnyDiscriminatorType(
return resolution.getLegacyResolvedBasicType(); return resolution.getLegacyResolvedBasicType();
} }
else {
final ClassLoaderService classLoaderService =
bootstrapContext.getServiceRegistry().requireService( ClassLoaderService.class );
try {
final Object typeInstance = typeInstance( typeName, classLoaderService.classForName( typeName ) );
final ClassLoaderService classLoaderService = bootstrapContext if ( typeInstance instanceof ParameterizedType ) {
.getServiceRegistry() if ( parameters != null ) {
.getService( ClassLoaderService.class ); Properties properties = new Properties();
properties.putAll( parameters );
try { ( (ParameterizedType) typeInstance ).setParameterValues( properties );
final Class<?> typeJavaType = classLoaderService.classForName( typeName ); }
final Object typeInstance;
if ( metadataBuildingContext.getBuildingOptions().disallowExtensionsInCdi() ) {
typeInstance = FallbackBeanInstanceProducer.INSTANCE.produceBeanInstance( typeJavaType );
}
else {
final ManagedBeanRegistry beanRegistry = bootstrapContext
.getServiceRegistry()
.getService( ManagedBeanRegistry.class );
final String beanName = typeName + ":" + TypeDefinition.NAME_COUNTER.getAndIncrement();
final ManagedBean<?> bean = beanRegistry.getBean( beanName, typeJavaType );
typeInstance = bean.getBeanInstance();
}
if ( typeInstance instanceof ParameterizedType ) {
if ( parameters != null ) {
Properties properties = new Properties();
properties.putAll( parameters );
( (ParameterizedType) typeInstance ).setParameterValues( properties );
} }
if ( typeInstance instanceof UserType ) {
return new CustomType<>( (UserType<?>) typeInstance, typeConfiguration);
}
return (BasicType<?>) typeInstance;
}
catch (ClassLoadingException e) {
log.debugf( "Unable to load explicit any-discriminator type name as Java Class - %s", typeName );
} }
if ( typeInstance instanceof UserType ) { throw new org.hibernate.MappingException(
//noinspection unchecked String.format(
return new CustomType<>( Locale.ROOT,
(UserType<Object>) typeInstance, "Unable to resolve explicit any-discriminator type name - %s",
bootstrapContext.getTypeConfiguration() typeName
); )
} );
assert typeInstance instanceof BasicType;
return (BasicType<?>) typeInstance;
}
catch (ClassLoadingException e) {
log.debugf( "Unable to load explicit any-discriminator type name as Java Class - %s", typeName );
} }
}
throw new org.hibernate.MappingException( private Object typeInstance(String typeName, Class<?> typeJavaType) {
String.format( if ( metadataBuildingContext.getBuildingOptions().disallowExtensionsInCdi() ) {
Locale.ROOT, return FallbackBeanInstanceProducer.INSTANCE.produceBeanInstance( typeJavaType );
"Unable to resolve explicit any-discriminator type name - %s", }
typeName else {
) final String beanName = typeName + ":" + TypeDefinition.NAME_COUNTER.getAndIncrement();
); return metadataBuildingContext.getBootstrapContext()
.getServiceRegistry().requireService( ManagedBeanRegistry.class )
.getBean( beanName, typeJavaType ).getBeanInstance();
}
} }
private void prepareValueTypeViaReflection( private void prepareValueTypeViaReflection(

View File

@ -28,8 +28,7 @@ public BasicTypeRegistration(BasicType<?> basicType, String[] registrationKeys)
} }
public BasicTypeRegistration(UserType<?> type, String[] keys, TypeConfiguration typeConfiguration) { public BasicTypeRegistration(UserType<?> type, String[] keys, TypeConfiguration typeConfiguration) {
//noinspection unchecked this( new CustomType<>( type, keys, typeConfiguration ), keys );
this( new CustomType<>( (UserType<Object>) type, keys, typeConfiguration ), keys );
} }
public BasicType<?> getBasicType() { public BasicType<?> getBasicType() {

View File

@ -250,7 +250,7 @@ public static java.lang.reflect.Type reflectedPropertyType(
String name, String name,
ClassLoaderService classLoaderService) throws MappingException { ClassLoaderService classLoaderService) throws MappingException {
try { try {
Class clazz = classLoaderService.classForName( className ); Class<?> clazz = classLoaderService.classForName( className );
return getter( clazz, name ).getReturnType(); return getter( clazz, name ).getReturnType();
} }
catch ( ClassLoadingException e ) { catch ( ClassLoadingException e ) {
@ -368,7 +368,7 @@ public static <T> Constructor<T> getConstructor(
try { try {
constructor = clazz.getDeclaredConstructor( constructorArgs ); constructor = clazz.getDeclaredConstructor( constructorArgs );
try { try {
ReflectHelper.ensureAccessibility( constructor ); ensureAccessibility( constructor );
} }
catch ( SecurityException e ) { catch ( SecurityException e ) {
constructor = null; constructor = null;
@ -425,11 +425,9 @@ else if ( containerClass == Object.class ) {
} }
public static void ensureAccessibility(AccessibleObject accessibleObject) { public static void ensureAccessibility(AccessibleObject accessibleObject) {
if ( accessibleObject.isAccessible() ) { if ( !accessibleObject.isAccessible() ) {
return; accessibleObject.setAccessible( true );
} }
accessibleObject.setAccessible( true );
} }
private static Field locateField(Class clazz, String propertyName) { private static Field locateField(Class clazz, String propertyName) {

View File

@ -67,6 +67,7 @@
import jakarta.persistence.TemporalType; import jakarta.persistence.TemporalType;
import static java.lang.Boolean.parseBoolean; import static java.lang.Boolean.parseBoolean;
import static org.hibernate.internal.util.collections.CollectionHelper.isNotEmpty;
import static org.hibernate.mapping.MappingHelper.injectParameters; import static org.hibernate.mapping.MappingHelper.injectParameters;
/** /**
@ -260,14 +261,14 @@ private void checkSelectable(Selectable incomingColumn) {
final Selectable column = getColumn(); final Selectable column = getColumn();
if ( column == incomingColumn || column.getText().equals( incomingColumn.getText() ) ) { if ( column == incomingColumn || column.getText().equals( incomingColumn.getText() ) ) {
log.debugf( "Skipping column re-registration: %s.%s", getTable().getName(), column.getText() ); log.debugf( "Skipping column re-registration: %s.%s", getTable().getName(), column.getText() );
return;
} }
// else {
// throw new IllegalStateException( // throw new IllegalStateException(
// "BasicValue [" + ownerName + "." + propertyName + // "BasicValue [" + ownerName + "." + propertyName +
// "] already had column associated: `" + column.getText() + // "] already had column associated: `" + column.getText() +
// "` -> `" + incomingColumn.getText() + "`" // "` -> `" + incomingColumn.getText() + "`"
// ); // );
// }
} }
@Override @Override
@ -390,12 +391,13 @@ public SelectablePath createSelectablePath(String selectableName) {
} }
protected Resolution<?> buildResolution() { protected Resolution<?> buildResolution() {
Properties typeParameters = getTypeParameters(); final Properties typeParameters = getTypeParameters();
if ( typeParameters != null if ( typeParameters != null
&& parseBoolean( typeParameters.getProperty(DynamicParameterizedType.IS_DYNAMIC) ) && parseBoolean( typeParameters.getProperty(DynamicParameterizedType.IS_DYNAMIC) )
&& typeParameters.get(DynamicParameterizedType.PARAMETER_TYPE) == null ) { && typeParameters.get(DynamicParameterizedType.PARAMETER_TYPE) == null ) {
createParameterImpl(); createParameterImpl();
} }
if ( explicitTypeName != null ) { if ( explicitTypeName != null ) {
return interpretExplicitlyNamedType( return interpretExplicitlyNamedType(
explicitTypeName, explicitTypeName,
@ -410,108 +412,115 @@ && parseBoolean( typeParameters.getProperty(DynamicParameterizedType.IS_DYNAMIC)
); );
} }
if ( isVersion() ) { if ( isVersion() ) {
return VersionResolution.from( implicitJavaTypeAccess, timeZoneStorageType, getBuildingContext() ); return VersionResolution.from( implicitJavaTypeAccess, timeZoneStorageType, getBuildingContext() );
} }
// determine JavaType if we can // determine JavaType if we can
final BasicJavaType<?> explicitJavaType =
final BasicJavaType explicitJavaType = explicitJavaTypeAccess == null ? null explicitJavaTypeAccess == null ? null : explicitJavaTypeAccess.apply( getTypeConfiguration() );
: explicitJavaTypeAccess.apply( getTypeConfiguration() );
final JavaType<?> javaType = determineJavaType( explicitJavaType ); final JavaType<?> javaType = determineJavaType( explicitJavaType );
final ConverterDescriptor attributeConverterDescriptor = getAttributeConverterDescriptor(); final ConverterDescriptor attributeConverterDescriptor = getAttributeConverterDescriptor();
final Selectable column = getColumn(); return attributeConverterDescriptor != null
if ( attributeConverterDescriptor != null ) { ? converterResolution( javaType, attributeConverterDescriptor )
final ManagedBeanRegistry managedBeanRegistry = getServiceRegistry().getService( ManagedBeanRegistry.class ); : resolution( explicitJavaType, javaType );
}
final NamedConverterResolution<?> converterResolution = NamedConverterResolution.from( private Resolution<?> resolution(BasicJavaType explicitJavaType, JavaType<?> javaType) {
attributeConverterDescriptor, final JavaType<?> basicJavaType;
explicitJavaTypeAccess, final JdbcType jdbcType;
explicitJdbcTypeAccess, if ( explicitJdbcTypeAccess != null ) {
explicitMutabilityPlanAccess, final TypeConfiguration typeConfiguration = getTypeConfiguration();
this, jdbcType = explicitJdbcTypeAccess.apply( typeConfiguration );
new JpaAttributeConverterCreationContext() { basicJavaType = javaType == null && jdbcType != null
@Override ? jdbcType.getJdbcRecommendedJavaTypeMapping(null, null, typeConfiguration)
public ManagedBeanRegistry getManagedBeanRegistry() { : javaType;
return managedBeanRegistry; }
} else {
@Override jdbcType = null;
public TypeConfiguration getTypeConfiguration() { basicJavaType = javaType;
return BasicValue.this.getTypeConfiguration();
}
},
getBuildingContext()
);
if ( javaType instanceof BasicPluralJavaType<?>
&& !attributeConverterDescriptor.getDomainValueResolvedType()
.getErasedType()
.isAssignableFrom( javaType.getJavaTypeClass() ) ) {
// In this case, the converter applies to the element of a BasicPluralJavaType
final BasicPluralJavaType<?> containerJtd = (BasicPluralJavaType<?>) javaType;
final BasicType registeredElementType = converterResolution.getLegacyResolvedBasicType();
final BasicType<?> registeredType = registeredElementType == null ? null
: containerJtd.resolveType(
getTypeConfiguration(),
getDialect(),
registeredElementType,
column instanceof ColumnTypeInformation ? (ColumnTypeInformation) column : null,
this
);
if ( registeredType != null ) {
getTypeConfiguration().getBasicTypeRegistry().register( registeredType );
return new InferredBasicValueResolution(
registeredType,
registeredType.getJavaTypeDescriptor(),
registeredType.getJavaTypeDescriptor(),
registeredType.getJdbcType(),
registeredType,
null
);
}
}
return converterResolution;
} }
final JdbcType jdbcType = explicitJdbcTypeAccess != null
? explicitJdbcTypeAccess.apply( getTypeConfiguration() )
: null;
final JavaType<?> basicJavaType = javaType == null && jdbcType != null
? jdbcType.getJdbcRecommendedJavaTypeMapping( null, null, getTypeConfiguration() )
: javaType;
if ( basicJavaType == null ) { if ( basicJavaType == null ) {
throw new MappingException( "Unable to determine JavaType to use : " + this ); throw new MappingException( "Unable to determine JavaType to use : " + this );
} }
final TypeDefinition autoAppliedTypeDef = basicJavaType instanceof BasicJavaType<?> if ( basicJavaType instanceof BasicJavaType<?>
? getBuildingContext().getTypeDefinitionRegistry().resolveAutoApplied( (BasicJavaType<?>) basicJavaType )
: null;
if ( autoAppliedTypeDef != null
&& ( !basicJavaType.getJavaTypeClass().isEnum() || enumerationStyle == null ) ) { && ( !basicJavaType.getJavaTypeClass().isEnum() || enumerationStyle == null ) ) {
log.debug( "BasicValue resolution matched auto-applied type-definition" ); final TypeDefinition autoAppliedTypeDef =
return autoAppliedTypeDef.resolve( typeParameters, null, getBuildingContext(), this ); getBuildingContext().getTypeDefinitionRegistry()
.resolveAutoApplied( (BasicJavaType<?>) basicJavaType );
if ( autoAppliedTypeDef != null ) {
log.debug("BasicValue resolution matched auto-applied type-definition");
return autoAppliedTypeDef.resolve( getTypeParameters(), null, getBuildingContext(), this );
}
} }
else {
return InferredBasicValueResolver.from( return InferredBasicValueResolver.from(
explicitJavaType, explicitJavaType,
jdbcType, jdbcType,
resolvedJavaType, resolvedJavaType,
this::determineReflectedJavaType, this::determineReflectedJavaType,
explicitMutabilityPlanAccess, explicitMutabilityPlanAccess,
this, this,
getTable(), getTable(),
column, getColumn(),
ownerName, ownerName,
propertyName, propertyName,
getBuildingContext() getBuildingContext()
);
}
private Resolution<?> converterResolution(JavaType<?> javaType, ConverterDescriptor attributeConverterDescriptor) {
final ManagedBeanRegistry managedBeanRegistry = getServiceRegistry().getService( ManagedBeanRegistry.class );
final NamedConverterResolution<?> converterResolution = NamedConverterResolution.from(
attributeConverterDescriptor,
explicitJavaTypeAccess,
explicitJdbcTypeAccess,
explicitMutabilityPlanAccess,
this,
new JpaAttributeConverterCreationContext() {
@Override
public ManagedBeanRegistry getManagedBeanRegistry() {
return managedBeanRegistry;
}
@Override
public TypeConfiguration getTypeConfiguration() {
return BasicValue.this.getTypeConfiguration();
}
},
getBuildingContext()
);
if ( javaType instanceof BasicPluralJavaType<?>
&& !attributeConverterDescriptor.getDomainValueResolvedType().getErasedType()
.isAssignableFrom( javaType.getJavaTypeClass() ) ) {
// In this case, the converter applies to the element of a BasicPluralJavaType
final BasicPluralJavaType<?> containerJtd = (BasicPluralJavaType<?>) javaType;
final BasicType registeredElementType = converterResolution.getLegacyResolvedBasicType();
final Selectable column = getColumn();
final BasicType<?> registeredType = registeredElementType == null ? null
: containerJtd.resolveType(
getTypeConfiguration(),
getDialect(),
registeredElementType,
column instanceof ColumnTypeInformation ? (ColumnTypeInformation) column : null,
this
); );
if ( registeredType != null ) {
getTypeConfiguration().getBasicTypeRegistry().register( registeredType );
return new InferredBasicValueResolution(
registeredType,
registeredType.getJavaTypeDescriptor(),
registeredType.getJavaTypeDescriptor(),
registeredType.getJdbcType(),
registeredType,
null
);
}
} }
return converterResolution;
} }
private JavaType<?> determineJavaType(JavaType<?> explicitJavaType) { private JavaType<?> determineJavaType(JavaType<?> explicitJavaType) {
@ -549,7 +558,7 @@ else if ( ownerName != null && propertyName != null ) {
impliedJavaType = ReflectHelper.reflectedPropertyType( impliedJavaType = ReflectHelper.reflectedPropertyType(
ownerName, ownerName,
propertyName, propertyName,
getServiceRegistry().getService( ClassLoaderService.class ) getServiceRegistry().requireService( ClassLoaderService.class )
); );
} }
else { else {
@ -666,7 +675,7 @@ public TypeConfiguration getTypeConfiguration() {
// see if the name is a UserType or BasicType implementor class name // see if the name is a UserType or BasicType implementor class name
final ClassLoaderService cls = serviceRegistry.getService( ClassLoaderService.class ); final ClassLoaderService cls = serviceRegistry.requireService( ClassLoaderService.class );
try { try {
final Class<?> typeNamedClass = cls.classForName( name ); final Class<?> typeNamedClass = cls.classForName( name );
@ -779,7 +788,7 @@ public void setTypeName(String typeName) {
if ( StringHelper.isNotEmpty( typeName ) ) { if ( StringHelper.isNotEmpty( typeName ) ) {
if ( typeName.startsWith( ConverterDescriptor.TYPE_NAME_PREFIX ) ) { if ( typeName.startsWith( ConverterDescriptor.TYPE_NAME_PREFIX ) ) {
final String converterClassName = typeName.substring( ConverterDescriptor.TYPE_NAME_PREFIX.length() ); final String converterClassName = typeName.substring( ConverterDescriptor.TYPE_NAME_PREFIX.length() );
final ClassLoaderService cls = getServiceRegistry().getService( ClassLoaderService.class ); final ClassLoaderService cls = getServiceRegistry().requireService( ClassLoaderService.class );
try { try {
final Class<AttributeConverter<?,?>> converterClass = cls.classForName( converterClassName ); final Class<AttributeConverter<?,?>> converterClass = cls.classForName( converterClassName );
setAttributeConverterDescriptor( new ClassBasedConverterDescriptor( setAttributeConverterDescriptor( new ClassBasedConverterDescriptor(
@ -803,65 +812,70 @@ public void setTypeName(String typeName) {
private static int COUNTER; private static int COUNTER;
public <T extends UserType<?>> void setExplicitCustomType(Class<T> explicitCustomType) { public void setExplicitCustomType(Class<? extends UserType<?>> explicitCustomType) {
if ( explicitCustomType != null ) { if ( explicitCustomType != null ) {
if ( resolution != null ) { if ( resolution != null ) {
throw new UnsupportedOperationException( "Unsupported attempt to set an explicit-custom-type when value is already resolved" ); throw new UnsupportedOperationException( "Unsupported attempt to set an explicit-custom-type when value is already resolved" );
} }
final BeanInstanceProducer instanceProducer =
getBuildingContext().getBootstrapContext().getCustomTypeProducer();
final Properties properties = new Properties();
if ( CollectionHelper.isNotEmpty( getTypeParameters() ) ) {
properties.putAll( getTypeParameters() );
}
if ( CollectionHelper.isNotEmpty( explicitLocalTypeParams ) ) {
properties.putAll( explicitLocalTypeParams );
}
final T typeInstance;
if ( getBuildingContext().getBuildingOptions().disallowExtensionsInCdi() ) {
typeInstance = FallbackBeanInstanceProducer.INSTANCE.produceBeanInstance( explicitCustomType );
}
else { else {
final boolean hasParameters = CollectionHelper.isNotEmpty( properties ); resolution = new UserTypeResolution<>(
new CustomType<>(
final ManagedBean<T> typeBean; getConfiguredUserTypeBean( explicitCustomType, getCustomTypeProperties() ),
if ( hasParameters ) { getTypeConfiguration()
final String name = explicitCustomType.getName() + COUNTER++; ),
typeBean = getServiceRegistry().getService( ManagedBeanRegistry.class ) null,
.getBean( name, explicitCustomType, instanceProducer ); getCustomTypeProperties()
} );
else {
typeBean = getServiceRegistry().getService( ManagedBeanRegistry.class )
.getBean( explicitCustomType, instanceProducer );
}
typeInstance = typeBean.getBeanInstance();
} }
}
}
if ( typeInstance instanceof TypeConfigurationAware ) { private Properties getCustomTypeProperties() {
( (TypeConfigurationAware) typeInstance ).setTypeConfiguration( getTypeConfiguration() ); final Properties properties = new Properties();
} if ( isNotEmpty( getTypeParameters() ) ) {
properties.putAll( getTypeParameters() );
}
if ( isNotEmpty( explicitLocalTypeParams ) ) {
properties.putAll( explicitLocalTypeParams );
}
return properties;
}
if ( typeInstance instanceof DynamicParameterizedType ) { private UserType<?> getConfiguredUserTypeBean(Class<? extends UserType<?>> explicitCustomType, Properties properties) {
if (parseBoolean(properties.getProperty(DynamicParameterizedType.IS_DYNAMIC))) { final UserType<?> typeInstance =
if (properties.get(DynamicParameterizedType.PARAMETER_TYPE) == null) { getBuildingContext().getBuildingOptions().disallowExtensionsInCdi()
final DynamicParameterizedType.ParameterType parameterType = makeParameterImpl(); ? FallbackBeanInstanceProducer.INSTANCE.produceBeanInstance( explicitCustomType )
properties.put(DynamicParameterizedType.PARAMETER_TYPE, parameterType); : getUserTypeBean( explicitCustomType, properties ).getBeanInstance();
}
if ( typeInstance instanceof TypeConfigurationAware ) {
final TypeConfigurationAware configurationAware = (TypeConfigurationAware) typeInstance;
configurationAware.setTypeConfiguration( getTypeConfiguration() );
}
if ( typeInstance instanceof DynamicParameterizedType ) {
if ( parseBoolean( properties.getProperty( DynamicParameterizedType.IS_DYNAMIC ) ) ) {
if ( properties.get( DynamicParameterizedType.PARAMETER_TYPE ) == null ) {
properties.put( DynamicParameterizedType.PARAMETER_TYPE, makeParameterImpl() );
} }
} }
}
injectParameters( typeInstance, properties ); injectParameters( typeInstance, properties);
// envers - grr // envers - grr
setTypeParameters( properties ); setTypeParameters( properties );
this.resolution = new UserTypeResolution( return typeInstance;
new CustomType<>( (UserType<?>) typeInstance, getTypeConfiguration() ), }
null,
properties private <T> ManagedBean<T> getUserTypeBean(Class<T> explicitCustomType, Properties properties) {
); final BeanInstanceProducer producer = getBuildingContext().getBootstrapContext().getCustomTypeProducer();
final ManagedBeanRegistry registry = getServiceRegistry().requireService( ManagedBeanRegistry.class );
if ( isNotEmpty( properties ) ) {
final String name = explicitCustomType.getName() + COUNTER++;
return registry.getBean( name, explicitCustomType, producer );
}
else {
return registry.getBean( explicitCustomType, producer );
} }
} }
@ -882,9 +896,9 @@ public Object accept(ValueVisitor visitor) {
@Internal @Internal
public boolean isDisallowedWrapperArray() { public boolean isDisallowedWrapperArray() {
return getBuildingContext().getBuildingOptions().getWrapperArrayHandling() == WrapperArrayHandling.DISALLOW return getBuildingContext().getBuildingOptions().getWrapperArrayHandling() == WrapperArrayHandling.DISALLOW
&& !isLob() && !isLob()
&& ( explicitJavaTypeAccess == null || explicitJavaTypeAccess.apply( getTypeConfiguration() ) == null ) && ( explicitJavaTypeAccess == null || explicitJavaTypeAccess.apply( getTypeConfiguration() ) == null )
&& isWrapperByteOrCharacterArray(); && isWrapperByteOrCharacterArray();
} }
private boolean isWrapperByteOrCharacterArray() { private boolean isWrapperByteOrCharacterArray() {

View File

@ -957,6 +957,7 @@ protected void createParameterImpl() {
throw new MappingException( "Could not create DynamicParameterizedType for type: " + typeName, e ); throw new MappingException( "Could not create DynamicParameterizedType for type: " + typeName, e );
} }
} }
public DynamicParameterizedType.ParameterType makeParameterImpl() { public DynamicParameterizedType.ParameterType makeParameterImpl() {
try { try {
final String[] columnNames = new String[ columns.size() ]; final String[] columnNames = new String[ columns.size() ];

View File

@ -113,16 +113,19 @@ else if ( AttributeConverter.class.isAssignableFrom( definedType ) ) {
else { else {
final JavaTypeRegistry jtdRegistry = typeConfiguration.getJavaTypeRegistry(); final JavaTypeRegistry jtdRegistry = typeConfiguration.getJavaTypeRegistry();
final JavaType<Object> registeredJtd = jtdRegistry.getDescriptor( definition.type() ); final JavaType<Object> registeredJtd = jtdRegistry.getDescriptor( definition.type() );
final ManagedBeanRegistry beanRegistry = sessionFactory.getServiceRegistry().getService( ManagedBeanRegistry.class ); final ManagedBeanRegistry beanRegistry =
sessionFactory.getServiceRegistry().requireService( ManagedBeanRegistry.class );
if ( BasicType.class.isAssignableFrom( registeredJtd.getJavaTypeClass() ) ) { if ( BasicType.class.isAssignableFrom( registeredJtd.getJavaTypeClass() ) ) {
final ManagedBean<BasicType<?>> typeBean = (ManagedBean) beanRegistry.getBean( registeredJtd.getJavaTypeClass() ); final ManagedBean<BasicType<?>> typeBean =
(ManagedBean) beanRegistry.getBean( registeredJtd.getJavaTypeClass() );
explicitType = typeBean.getBeanInstance(); explicitType = typeBean.getBeanInstance();
explicitJavaType = explicitType.getJavaTypeDescriptor(); explicitJavaType = explicitType.getJavaTypeDescriptor();
} }
else if ( UserType.class.isAssignableFrom( registeredJtd.getJavaTypeClass() ) ) { else if ( UserType.class.isAssignableFrom( registeredJtd.getJavaTypeClass() ) ) {
final ManagedBean<UserType<?>> userTypeBean = (ManagedBean) beanRegistry.getBean( registeredJtd.getJavaTypeClass() ); final ManagedBean<UserType<?>> userTypeBean =
(ManagedBean) beanRegistry.getBean( registeredJtd.getJavaTypeClass() );
// todo (6.0) : is this the best approach? or should we keep a Class<? extends UserType> -> @Type mapping somewhere? // todo (6.0) : is this the best approach? or should we keep a Class<? extends UserType> -> @Type mapping somewhere?
explicitType = new CustomType<>( (UserType<Object>) userTypeBean.getBeanInstance(), typeConfiguration ); explicitType = new CustomType<>( userTypeBean.getBeanInstance(), typeConfiguration );
explicitJavaType = explicitType.getJavaTypeDescriptor(); explicitJavaType = explicitType.getJavaTypeDescriptor();
} }
else { else {

View File

@ -68,7 +68,8 @@ public CustomType(UserType<J> userType, TypeConfiguration typeConfiguration) thr
this( userType, ArrayHelper.EMPTY_STRING_ARRAY, typeConfiguration ); this( userType, ArrayHelper.EMPTY_STRING_ARRAY, typeConfiguration );
} }
public CustomType(UserType<J> userType, String[] registrationKeys, TypeConfiguration typeConfiguration) throws MappingException { public CustomType(UserType<J> userType, String[] registrationKeys, TypeConfiguration typeConfiguration)
throws MappingException {
this.userType = userType; this.userType = userType;
name = userType.getClass().getName(); name = userType.getClass().getName();