Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public class InstantiationException extends HibernateException {
private final Class<?> clazz;

/**
* Constructs a {@code InstantiationException}.
* Constructs an {@code InstantiationException}.
*
* @param message A message explaining the exception condition
* @param clazz The Class we are attempting to instantiate
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,17 @@
*/
package org.hibernate.boot.model;

import java.lang.reflect.Constructor;
import java.util.Map;

import org.hibernate.InstantiationException;
import org.hibernate.Internal;
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;

import java.lang.reflect.Constructor;
import java.util.Map;

import static org.hibernate.internal.util.ReflectHelper.getConstructor;

/**
* {@link BeanInstanceProducer} implementation for building beans related to custom types.
*
Expand All @@ -31,20 +32,29 @@ public TypeBeanInstanceProducer(ConfigurationService configurationService) {

@Override
public <B> B produceBeanInstance(Class<B> beanType) {
try {
final Constructor<B> bootstrapContextAwareTypeConstructor = ReflectHelper.getConstructor(
beanType,
TypeBootstrapContext.class
);
if ( bootstrapContextAwareTypeConstructor != null ) {
return bootstrapContextAwareTypeConstructor.newInstance( this );
final Constructor<B> bootstrapContextAwareConstructor =
getConstructor( beanType, TypeBootstrapContext.class );
if ( bootstrapContextAwareConstructor != null ) {
try {
return bootstrapContextAwareConstructor.newInstance( this );
}
else {
return beanType.newInstance();
catch ( Exception e ) {
throw new InstantiationException( "Could not instantiate type", beanType, e );
}
}
catch ( Exception e ) {
throw new MappingException( "Could not instantiate Type: " + beanType.getName(), 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 );
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import java.util.Properties;
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.registry.StandardServiceRegistry;
import org.hibernate.boot.spi.BootstrapContext;
Expand All @@ -42,6 +41,7 @@
import org.hibernate.type.spi.TypeConfigurationAware;
import org.hibernate.usertype.UserType;

import static org.hibernate.boot.model.process.internal.InferredBasicValueResolver.resolveSqlTypeIndicators;
import static org.hibernate.mapping.MappingHelper.injectParameters;

/**
Expand Down Expand Up @@ -131,26 +131,28 @@ private BasicValue.Resolution<?> createResolution(
);
}

private static BasicValue.Resolution<?> createResolution(
private static <T> BasicValue.Resolution<T> createResolution(
String name,
Class<?> typeImplementorClass,
Class<T> typeImplementorClass,
Map<?,?> parameters,
Map<?,?> usageSiteProperties,
JdbcTypeIndicators indicators,
MetadataBuildingContext context) {
final BootstrapContext bootstrapContext = context.getBootstrapContext();
final TypeConfiguration typeConfiguration = bootstrapContext.getTypeConfiguration();
final BeanInstanceProducer instanceProducer = bootstrapContext.getCustomTypeProducer();
final boolean isKnownType = Type.class.isAssignableFrom( typeImplementorClass )
final boolean isKnownType =
Type.class.isAssignableFrom( typeImplementorClass )
|| UserType.class.isAssignableFrom( typeImplementorClass );

// support for AttributeConverter would be nice too
if ( isKnownType ) {
final Object typeInstance = instantiateType( bootstrapContext.getServiceRegistry(),
final T typeInstance = instantiateType( bootstrapContext.getServiceRegistry(),
context.getBuildingOptions(), name, typeImplementorClass, instanceProducer );

if ( typeInstance instanceof TypeConfigurationAware ) {
( (TypeConfigurationAware) typeInstance ).setTypeConfiguration( typeConfiguration );
final TypeConfigurationAware configurationAware = (TypeConfigurationAware) typeInstance;
configurationAware.setTypeConfiguration( typeConfiguration );
}

final Properties combinedTypeParameters = new Properties();
Expand All @@ -164,22 +166,23 @@ private static BasicValue.Resolution<?> createResolution(
injectParameters( typeInstance, combinedTypeParameters );

if ( typeInstance instanceof UserType ) {
final UserType<?> userType = (UserType<?>) typeInstance;
final CustomType<?> customType = new CustomType<>( userType, typeConfiguration );

return new UserTypeResolution( customType, null, combinedTypeParameters );
@SuppressWarnings("unchecked")
final UserType<T> userType = (UserType<T>) typeInstance;
final CustomType<T> customType = new CustomType<>( userType, typeConfiguration );
return new UserTypeResolution<>( customType, null, combinedTypeParameters );
}

if ( typeInstance instanceof BasicType ) {
final BasicType<?> resolvedBasicType = (BasicType<?>) typeInstance;
@SuppressWarnings("unchecked")
final BasicType<T> resolvedBasicType = (BasicType<T>) typeInstance;
return new BasicValue.Resolution<>() {
@Override
public JdbcMapping getJdbcMapping() {
return resolvedBasicType;
}

@Override @SuppressWarnings({"rawtypes", "unchecked"})
public BasicType getLegacyResolvedBasicType() {
@Override
public BasicType<T> getLegacyResolvedBasicType() {
return resolvedBasicType;
}

Expand All @@ -188,8 +191,8 @@ public Properties getCombinedTypeParameters() {
return combinedTypeParameters;
}

@Override @SuppressWarnings({"rawtypes", "unchecked"})
public JavaType getDomainJavaType() {
@Override
public JavaType<T> getDomainJavaType() {
return resolvedBasicType.getMappedJavaType();
}

Expand All @@ -204,12 +207,12 @@ public JdbcType getJdbcType() {
}

@Override
public BasicValueConverter getValueConverter() {
public BasicValueConverter<T,?> getValueConverter() {
return resolvedBasicType.getValueConverter();
}

@Override @SuppressWarnings({"rawtypes", "unchecked"})
public MutabilityPlan getMutabilityPlan() {
@Override
public MutabilityPlan<T> getMutabilityPlan() {
// a TypeDefinition does not explicitly provide a MutabilityPlan (yet?)
return resolvedBasicType.isMutable()
? getDomainJavaType().getMutabilityPlan()
Expand All @@ -220,37 +223,35 @@ public MutabilityPlan getMutabilityPlan() {
}

// 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 ) ) {
@SuppressWarnings({"rawtypes", "unchecked"})
final SerializableType legacyType = new SerializableType( typeImplementorClass );
return createBasicTypeResolution( legacyType, typeImplementorClass, indicators, typeConfiguration );
legacyType = new SerializableType( typeImplementorClass );
}

if ( typeImplementorClass.isInterface() ) {
return createBasicTypeResolution( new JavaObjectType(), typeImplementorClass, indicators, typeConfiguration );
else if ( typeImplementorClass.isInterface() ) {
legacyType = (BasicType<T>) new JavaObjectType();
}
else {
throw new IllegalArgumentException( "Named type [" + typeImplementorClass
+ "] did not implement BasicType nor UserType" );
}

throw new IllegalArgumentException(
"Named type [" + typeImplementorClass + "] did not implement BasicType nor UserType"
);
return createBasicTypeResolution( legacyType, typeImplementorClass, indicators, typeConfiguration );
}

private static BasicValue.Resolution<Object> createBasicTypeResolution(
BasicType<?> type,
Class<?> typeImplementorClass,
private static <T> BasicValue.Resolution<T> createBasicTypeResolution(
BasicType<T> type,
Class<? extends T> typeImplementorClass,
JdbcTypeIndicators indicators,
TypeConfiguration typeConfiguration
) {
final JavaType<Serializable> jtd = typeConfiguration
.getJavaTypeRegistry()
.resolveDescriptor( typeImplementorClass );
TypeConfiguration typeConfiguration) {
final JavaType<T> jtd = typeConfiguration.getJavaTypeRegistry().resolveDescriptor( typeImplementorClass );
final JdbcType jdbcType = typeConfiguration.getJdbcTypeRegistry().getDescriptor( Types.VARBINARY );
final BasicType<Serializable> resolved = InferredBasicValueResolver.resolveSqlTypeIndicators(
indicators,
typeConfiguration.getBasicTypeRegistry().resolve( jtd, jdbcType ),
jtd
);
final BasicType<T> basicType = typeConfiguration.getBasicTypeRegistry().resolve( jtd, jdbcType );
final BasicType<T> resolved = resolveSqlTypeIndicators( indicators, basicType, jtd );

return new BasicValue.Resolution<>() {
@Override
Expand All @@ -259,14 +260,12 @@ public JdbcMapping getJdbcMapping() {
}

@Override
@SuppressWarnings({ "rawtypes", "unchecked" })
public BasicType getLegacyResolvedBasicType() {
public BasicType<T> getLegacyResolvedBasicType() {
return type;
}

@Override
@SuppressWarnings({ "rawtypes", "unchecked" })
public JavaType getDomainJavaType() {
public JavaType<T> getDomainJavaType() {
return resolved.getMappedJavaType();
}

Expand All @@ -281,13 +280,12 @@ public JdbcType getJdbcType() {
}

@Override
public BasicValueConverter getValueConverter() {
public BasicValueConverter<T,?> getValueConverter() {
return resolved.getValueConverter();
}

@Override
@SuppressWarnings({ "rawtypes", "unchecked" })
public MutabilityPlan getMutabilityPlan() {
public MutabilityPlan<T> getMutabilityPlan() {
// a TypeDefinition does not explicitly provide a MutabilityPlan (yet?)
return resolved.isMutable()
? getDomainJavaType().getMutabilityPlan()
Expand All @@ -296,20 +294,20 @@ public MutabilityPlan getMutabilityPlan() {
};
}

private static Object instantiateType(
private static <T> T instantiateType(
StandardServiceRegistry serviceRegistry,
MetadataBuildingOptions buildingOptions,
String name,
Class<?> typeImplementorClass,
Class<T> typeImplementorClass,
BeanInstanceProducer instanceProducer) {
if ( buildingOptions.disallowExtensionsInCdi() ) {
return name != null
? instanceProducer.produceBeanInstance( name, typeImplementorClass )
: instanceProducer.produceBeanInstance( typeImplementorClass );
}
else {
final ManagedBeanRegistry beanRegistry = serviceRegistry.getService( ManagedBeanRegistry.class );
final ManagedBean<?> typeBean = name != null
final ManagedBeanRegistry beanRegistry = serviceRegistry.requireService( ManagedBeanRegistry.class );
final ManagedBean<T> typeBean = name != null
? beanRegistry.getBean( name, typeImplementorClass, instanceProducer )
: beanRegistry.getBean( typeImplementorClass, instanceProducer );
return typeBean.getBeanInstance();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
import org.hibernate.boot.model.convert.spi.RegisteredConversion;
import org.hibernate.boot.registry.StandardServiceRegistry;
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.MetadataBuildingContext;
import org.hibernate.dialect.Dialect;
Expand Down Expand Up @@ -601,6 +602,8 @@ private static void bindUserTypeRegistrations(
private static void handleUserTypeRegistration(
MetadataBuildingContext context,
TypeRegistration compositeTypeRegistration) {
// TODO: check that the two classes agree, i.e. that
// the user type knows how to handle the type
context.getMetadataCollector().registerUserType(
compositeTypeRegistration.basicClass(),
compositeTypeRegistration.userType()
Expand All @@ -610,6 +613,8 @@ private static void handleUserTypeRegistration(
private static void handleCompositeUserTypeRegistration(
MetadataBuildingContext context,
CompositeTypeRegistration compositeTypeRegistration) {
// TODO: check that the two classes agree, i.e. that
// the user type knows how to handle the type
context.getMetadataCollector().registerCompositeUserType(
compositeTypeRegistration.embeddableClass(),
compositeTypeRegistration.userType()
Expand Down Expand Up @@ -755,25 +760,21 @@ public Dialect getDialect() {
}

private static JdbcMapping resolveUserType(Class<UserType<?>> userTypeClass, MetadataBuildingContext context) {
final UserType<?> userType;
if ( context.getBuildingOptions().disallowExtensionsInCdi() ) {
userType = FallbackBeanInstanceProducer.INSTANCE.produceBeanInstance( userTypeClass );
}
else {
final StandardServiceRegistry serviceRegistry = context.getBootstrapContext().getServiceRegistry();
final ManagedBeanRegistry beanRegistry = serviceRegistry.getService( ManagedBeanRegistry.class );
userType = beanRegistry.getBean( userTypeClass ).getBeanInstance();
}

final UserType<?> userType = context.getBuildingOptions().disallowExtensionsInCdi()
? FallbackBeanInstanceProducer.INSTANCE.produceBeanInstance( userTypeClass )
: context.getBootstrapContext().getServiceRegistry()
.requireService( ManagedBeanRegistry.class )
.getBean( userTypeClass ).getBeanInstance();
return new CustomType<>( userType, context.getBootstrapContext().getTypeConfiguration() );
}

private static JdbcMapping resolveAttributeConverter(Class<AttributeConverter<?, ?>> type, MetadataBuildingContext context) {
final StandardServiceRegistry serviceRegistry = context.getBootstrapContext().getServiceRegistry();
final ManagedBeanRegistry beanRegistry = serviceRegistry.getService( ManagedBeanRegistry.class );
final BootstrapContext bootstrapContext = context.getBootstrapContext();
final ManagedBeanRegistry beanRegistry =
bootstrapContext.getServiceRegistry().requireService( ManagedBeanRegistry.class );
final ManagedBean<AttributeConverter<?, ?>> bean = beanRegistry.getBean( type );

final TypeConfiguration typeConfiguration = context.getBootstrapContext().getTypeConfiguration();
final TypeConfiguration typeConfiguration = bootstrapContext.getTypeConfiguration();
final JavaTypeRegistry jtdRegistry = typeConfiguration.getJavaTypeRegistry();
final JavaType<? extends AttributeConverter<?,?>> converterJtd = jtdRegistry.resolveDescriptor( bean.getBeanClass() );

Expand Down
Loading