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) {
final Constructor<B> bootstrapContextAwareConstructor =
getConstructor( beanType, TypeBootstrapContext.class );
if ( bootstrapContextAwareConstructor != null ) {
try { try {
final Constructor<B> bootstrapContextAwareTypeConstructor = ReflectHelper.getConstructor( return bootstrapContextAwareConstructor.newInstance( this );
beanType,
TypeBootstrapContext.class
);
if ( bootstrapContextAwareTypeConstructor != null ) {
return bootstrapContextAwareTypeConstructor.newInstance( this );
}
else {
return beanType.newInstance();
}
} }
catch ( Exception e ) { catch ( Exception e ) {
throw new MappingException( "Could not instantiate Type: " + beanType.getName(), e ); throw new InstantiationException( "Could not instantiate type", beanType, e );
}
}
else {
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 );
}
private static <T> BasicValue.Resolution<T> resolveLegacyCases(
Class<T> typeImplementorClass, JdbcTypeIndicators indicators, TypeConfiguration typeConfiguration) {
final BasicType<T> legacyType;
if ( Serializable.class.isAssignableFrom( typeImplementorClass ) ) { if ( Serializable.class.isAssignableFrom( typeImplementorClass ) ) {
@SuppressWarnings({"rawtypes", "unchecked"}) legacyType = new SerializableType( typeImplementorClass );
final SerializableType 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 ); return createBasicTypeResolution( legacyType, typeImplementorClass, indicators, typeConfiguration );
} }
if ( typeImplementorClass.isInterface() ) { private static <T> BasicValue.Resolution<T> createBasicTypeResolution(
return createBasicTypeResolution( new JavaObjectType(), typeImplementorClass, indicators, typeConfiguration ); BasicType<T> type,
} Class<? extends T> typeImplementorClass,
throw new IllegalArgumentException(
"Named type [" + typeImplementorClass + "] did not implement BasicType nor UserType"
);
}
private static BasicValue.Resolution<Object> createBasicTypeResolution(
BasicType<?> type,
Class<?> 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,25 +2375,11 @@ private BasicType<?> resolveExplicitlyNamedAnyDiscriminatorType(
return resolution.getLegacyResolvedBasicType(); return resolution.getLegacyResolvedBasicType();
} }
final ClassLoaderService classLoaderService = bootstrapContext
.getServiceRegistry()
.getService( ClassLoaderService.class );
try {
final Class<?> typeJavaType = classLoaderService.classForName( typeName );
final Object typeInstance;
if ( metadataBuildingContext.getBuildingOptions().disallowExtensionsInCdi() ) {
typeInstance = FallbackBeanInstanceProducer.INSTANCE.produceBeanInstance( typeJavaType );
}
else { else {
final ManagedBeanRegistry beanRegistry = bootstrapContext final ClassLoaderService classLoaderService =
.getServiceRegistry() bootstrapContext.getServiceRegistry().requireService( ClassLoaderService.class );
.getService( ManagedBeanRegistry.class ); try {
final String beanName = typeName + ":" + TypeDefinition.NAME_COUNTER.getAndIncrement(); final Object typeInstance = typeInstance( typeName, classLoaderService.classForName( typeName ) );
final ManagedBean<?> bean = beanRegistry.getBean( beanName, typeJavaType );
typeInstance = bean.getBeanInstance();
}
if ( typeInstance instanceof ParameterizedType ) { if ( typeInstance instanceof ParameterizedType ) {
if ( parameters != null ) { if ( parameters != null ) {
@ -2406,14 +2390,9 @@ private BasicType<?> resolveExplicitlyNamedAnyDiscriminatorType(
} }
if ( typeInstance instanceof UserType ) { if ( typeInstance instanceof UserType ) {
//noinspection unchecked return new CustomType<>( (UserType<?>) typeInstance, typeConfiguration);
return new CustomType<>(
(UserType<Object>) typeInstance,
bootstrapContext.getTypeConfiguration()
);
} }
assert typeInstance instanceof BasicType;
return (BasicType<?>) typeInstance; return (BasicType<?>) typeInstance;
} }
catch (ClassLoadingException e) { catch (ClassLoadingException e) {
@ -2428,6 +2407,19 @@ private BasicType<?> resolveExplicitlyNamedAnyDiscriminatorType(
) )
); );
} }
}
private Object typeInstance(String typeName, Class<?> typeJavaType) {
if ( metadataBuildingContext.getBuildingOptions().disallowExtensionsInCdi() ) {
return FallbackBeanInstanceProducer.INSTANCE.produceBeanInstance( typeJavaType );
}
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(
MappingDocument sourceDocument, MappingDocument sourceDocument,

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,12 +425,10 @@ 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) {
if ( clazz == null || Object.class.equals( clazz ) ) { if ( clazz == null || Object.class.equals( clazz ) ) {

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,23 +412,67 @@ && 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 );
}
private Resolution<?> resolution(BasicJavaType explicitJavaType, JavaType<?> javaType) {
final JavaType<?> basicJavaType;
final JdbcType jdbcType;
if ( explicitJdbcTypeAccess != null ) {
final TypeConfiguration typeConfiguration = getTypeConfiguration();
jdbcType = explicitJdbcTypeAccess.apply( typeConfiguration );
basicJavaType = javaType == null && jdbcType != null
? jdbcType.getJdbcRecommendedJavaTypeMapping(null, null, typeConfiguration)
: javaType;
}
else {
jdbcType = null;
basicJavaType = javaType;
}
if ( basicJavaType == null ) {
throw new MappingException( "Unable to determine JavaType to use : " + this );
}
if ( basicJavaType instanceof BasicJavaType<?>
&& ( !basicJavaType.getJavaTypeClass().isEnum() || enumerationStyle == null ) ) {
final TypeDefinition autoAppliedTypeDef =
getBuildingContext().getTypeDefinitionRegistry()
.resolveAutoApplied( (BasicJavaType<?>) basicJavaType );
if ( autoAppliedTypeDef != null ) {
log.debug("BasicValue resolution matched auto-applied type-definition");
return autoAppliedTypeDef.resolve( getTypeParameters(), null, getBuildingContext(), this );
}
}
return InferredBasicValueResolver.from(
explicitJavaType,
jdbcType,
resolvedJavaType,
this::determineReflectedJavaType,
explicitMutabilityPlanAccess,
this,
getTable(),
getColumn(),
ownerName,
propertyName,
getBuildingContext()
);
}
private Resolution<?> converterResolution(JavaType<?> javaType, ConverterDescriptor attributeConverterDescriptor) {
final ManagedBeanRegistry managedBeanRegistry = getServiceRegistry().getService( ManagedBeanRegistry.class );
final NamedConverterResolution<?> converterResolution = NamedConverterResolution.from( final NamedConverterResolution<?> converterResolution = NamedConverterResolution.from(
attributeConverterDescriptor, attributeConverterDescriptor,
explicitJavaTypeAccess, explicitJavaTypeAccess,
@ -447,12 +493,12 @@ public TypeConfiguration getTypeConfiguration() {
); );
if ( javaType instanceof BasicPluralJavaType<?> if ( javaType instanceof BasicPluralJavaType<?>
&& !attributeConverterDescriptor.getDomainValueResolvedType() && !attributeConverterDescriptor.getDomainValueResolvedType().getErasedType()
.getErasedType()
.isAssignableFrom( javaType.getJavaTypeClass() ) ) { .isAssignableFrom( javaType.getJavaTypeClass() ) ) {
// In this case, the converter applies to the element of a BasicPluralJavaType // In this case, the converter applies to the element of a BasicPluralJavaType
final BasicPluralJavaType<?> containerJtd = (BasicPluralJavaType<?>) javaType; final BasicPluralJavaType<?> containerJtd = (BasicPluralJavaType<?>) javaType;
final BasicType registeredElementType = converterResolution.getLegacyResolvedBasicType(); final BasicType registeredElementType = converterResolution.getLegacyResolvedBasicType();
final Selectable column = getColumn();
final BasicType<?> registeredType = registeredElementType == null ? null final BasicType<?> registeredType = registeredElementType == null ? null
: containerJtd.resolveType( : containerJtd.resolveType(
getTypeConfiguration(), getTypeConfiguration(),
@ -463,7 +509,6 @@ public TypeConfiguration getTypeConfiguration() {
); );
if ( registeredType != null ) { if ( registeredType != null ) {
getTypeConfiguration().getBasicTypeRegistry().register( registeredType ); getTypeConfiguration().getBasicTypeRegistry().register( registeredType );
return new InferredBasicValueResolution( return new InferredBasicValueResolution(
registeredType, registeredType,
registeredType.getJavaTypeDescriptor(), registeredType.getJavaTypeDescriptor(),
@ -478,42 +523,6 @@ public TypeConfiguration getTypeConfiguration() {
return converterResolution; 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 ) {
throw new MappingException( "Unable to determine JavaType to use : " + this );
}
final TypeDefinition autoAppliedTypeDef = basicJavaType instanceof BasicJavaType<?>
? getBuildingContext().getTypeDefinitionRegistry().resolveAutoApplied( (BasicJavaType<?>) basicJavaType )
: null;
if ( autoAppliedTypeDef != null
&& ( !basicJavaType.getJavaTypeClass().isEnum() || enumerationStyle == null ) ) {
log.debug( "BasicValue resolution matched auto-applied type-definition" );
return autoAppliedTypeDef.resolve( typeParameters, null, getBuildingContext(), this );
}
else {
return InferredBasicValueResolver.from(
explicitJavaType,
jdbcType,
resolvedJavaType,
this::determineReflectedJavaType,
explicitMutabilityPlanAccess,
this,
getTable(),
column,
ownerName,
propertyName,
getBuildingContext()
);
}
}
private JavaType<?> determineJavaType(JavaType<?> explicitJavaType) { private JavaType<?> determineJavaType(JavaType<?> explicitJavaType) {
JavaType<?> javaType = explicitJavaType; JavaType<?> 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" );
} }
else {
resolution = new UserTypeResolution<>(
new CustomType<>(
getConfiguredUserTypeBean( explicitCustomType, getCustomTypeProperties() ),
getTypeConfiguration()
),
null,
getCustomTypeProperties()
);
}
}
}
final BeanInstanceProducer instanceProducer = private Properties getCustomTypeProperties() {
getBuildingContext().getBootstrapContext().getCustomTypeProducer();
final Properties properties = new Properties(); final Properties properties = new Properties();
if ( CollectionHelper.isNotEmpty( getTypeParameters() ) ) { if ( isNotEmpty( getTypeParameters() ) ) {
properties.putAll( getTypeParameters() ); properties.putAll( getTypeParameters() );
} }
if ( CollectionHelper.isNotEmpty( explicitLocalTypeParams ) ) { if ( isNotEmpty( explicitLocalTypeParams ) ) {
properties.putAll( explicitLocalTypeParams ); properties.putAll( explicitLocalTypeParams );
} }
return properties;
}
final T typeInstance; private UserType<?> getConfiguredUserTypeBean(Class<? extends UserType<?>> explicitCustomType, Properties properties) {
if ( getBuildingContext().getBuildingOptions().disallowExtensionsInCdi() ) { final UserType<?> typeInstance =
typeInstance = FallbackBeanInstanceProducer.INSTANCE.produceBeanInstance( explicitCustomType ); getBuildingContext().getBuildingOptions().disallowExtensionsInCdi()
} ? FallbackBeanInstanceProducer.INSTANCE.produceBeanInstance( explicitCustomType )
else { : getUserTypeBean( explicitCustomType, properties ).getBeanInstance();
final boolean hasParameters = CollectionHelper.isNotEmpty( properties );
final ManagedBean<T> typeBean;
if ( hasParameters ) {
final String name = explicitCustomType.getName() + COUNTER++;
typeBean = getServiceRegistry().getService( ManagedBeanRegistry.class )
.getBean( name, explicitCustomType, instanceProducer );
}
else {
typeBean = getServiceRegistry().getService( ManagedBeanRegistry.class )
.getBean( explicitCustomType, instanceProducer );
}
typeInstance = typeBean.getBeanInstance();
}
if ( typeInstance instanceof TypeConfigurationAware ) { if ( typeInstance instanceof TypeConfigurationAware ) {
( (TypeConfigurationAware) typeInstance ).setTypeConfiguration( getTypeConfiguration() ); final TypeConfigurationAware configurationAware = (TypeConfigurationAware) typeInstance;
configurationAware.setTypeConfiguration( getTypeConfiguration() );
} }
if ( typeInstance instanceof DynamicParameterizedType ) { if ( typeInstance instanceof DynamicParameterizedType ) {
if (parseBoolean(properties.getProperty(DynamicParameterizedType.IS_DYNAMIC))) { if ( parseBoolean( properties.getProperty( DynamicParameterizedType.IS_DYNAMIC ) ) ) {
if (properties.get(DynamicParameterizedType.PARAMETER_TYPE) == null) { if ( properties.get( DynamicParameterizedType.PARAMETER_TYPE ) == null ) {
final DynamicParameterizedType.ParameterType parameterType = makeParameterImpl(); properties.put( DynamicParameterizedType.PARAMETER_TYPE, makeParameterImpl() );
properties.put(DynamicParameterizedType.PARAMETER_TYPE, parameterType);
} }
} }
} }
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 );
} }
} }

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();