HHH-14905 - Verify that custom JavaType and JdbcType registration combo works
This commit is contained in:
parent
9fec060fe2
commit
0eee5ff5b0
|
@ -39,6 +39,7 @@ import org.hibernate.metamodel.internal.ManagedTypeRepresentationResolverStandar
|
|||
import org.hibernate.metamodel.spi.ManagedTypeRepresentationResolver;
|
||||
import org.hibernate.query.sqm.function.SqmFunctionDescriptor;
|
||||
import org.hibernate.resource.beans.spi.BeanInstanceProducer;
|
||||
import org.hibernate.type.internal.BasicTypeImpl;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
import org.jboss.jandex.IndexView;
|
||||
|
@ -219,6 +220,19 @@ public class BootstrapContextImpl implements BootstrapContext {
|
|||
return cacheRegionDefinitions == null ? Collections.emptyList() : cacheRegionDefinitions;
|
||||
}
|
||||
|
||||
private final Map<String,BasicTypeImpl<?>> adHocBasicTypeRegistrations = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void registerAdHocBasicType(BasicTypeImpl<?> basicType) {
|
||||
adHocBasicTypeRegistrations.put( basicType.getName(), basicType );
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> BasicTypeImpl<T> resolveAdHocBasicType(String key) {
|
||||
//noinspection unchecked
|
||||
return (BasicTypeImpl<T>) adHocBasicTypeRegistrations.get( key );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
classmateContext.release();
|
||||
|
|
|
@ -26,6 +26,7 @@ import org.hibernate.jpa.spi.MutableJpaCompliance;
|
|||
import org.hibernate.metamodel.spi.ManagedTypeRepresentationResolver;
|
||||
import org.hibernate.query.sqm.function.SqmFunctionDescriptor;
|
||||
import org.hibernate.resource.beans.spi.BeanInstanceProducer;
|
||||
import org.hibernate.type.internal.BasicTypeImpl;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
import org.jboss.jandex.IndexView;
|
||||
|
@ -180,4 +181,14 @@ public interface BootstrapContext {
|
|||
* @todo verify this ^^
|
||||
*/
|
||||
void release();
|
||||
|
||||
/**
|
||||
* To support envers
|
||||
*/
|
||||
void registerAdHocBasicType(BasicTypeImpl<?> basicType);
|
||||
|
||||
/**
|
||||
* To support envers
|
||||
*/
|
||||
<T> BasicTypeImpl<T> resolveAdHocBasicType(String key);
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import org.hibernate.boot.model.process.internal.NamedBasicTypeResolution;
|
|||
import org.hibernate.boot.model.process.internal.NamedConverterResolution;
|
||||
import org.hibernate.boot.model.process.internal.UserTypeResolution;
|
||||
import org.hibernate.boot.model.process.internal.VersionResolution;
|
||||
import org.hibernate.boot.registry.StandardServiceRegistry;
|
||||
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
|
||||
import org.hibernate.boot.registry.classloading.spi.ClassLoadingException;
|
||||
import org.hibernate.boot.spi.BootstrapContext;
|
||||
|
@ -51,6 +52,7 @@ import org.hibernate.type.descriptor.java.JavaType;
|
|||
import org.hibernate.type.descriptor.java.MutabilityPlan;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcTypeDescriptorIndicators;
|
||||
import org.hibernate.type.internal.BasicTypeImpl;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
import org.hibernate.type.spi.TypeConfigurationAware;
|
||||
import org.hibernate.usertype.DynamicParameterizedType;
|
||||
|
@ -500,9 +502,8 @@ public class BasicValue extends SimpleValue implements JdbcTypeDescriptorIndicat
|
|||
TypeConfiguration typeConfiguration,
|
||||
MetadataBuildingContext context) {
|
||||
|
||||
final ManagedBeanRegistry managedBeanRegistry = context.getBootstrapContext()
|
||||
.getServiceRegistry()
|
||||
.getService( ManagedBeanRegistry.class );
|
||||
final StandardServiceRegistry serviceRegistry = context.getBootstrapContext().getServiceRegistry();
|
||||
final ManagedBeanRegistry managedBeanRegistry = serviceRegistry.getService( ManagedBeanRegistry.class );
|
||||
|
||||
final JpaAttributeConverterCreationContext converterCreationContext = new JpaAttributeConverterCreationContext() {
|
||||
@Override
|
||||
|
@ -519,8 +520,10 @@ public class BasicValue extends SimpleValue implements JdbcTypeDescriptorIndicat
|
|||
|
||||
// Name could refer to:
|
||||
// 1) a named converter - HBM support for JPA's AttributeConverter via its `type="..."` XML attribute
|
||||
// 2) basic type "resolution key"
|
||||
// 3) UserType or BasicType class name - directly, or through a TypeDefinition
|
||||
// 2) a "named composed" mapping - like (1), this is mainly to support envers since it tells
|
||||
// Hibernate the mappings via DOM. See `org.hibernate.type.internal.BasicTypeImpl`
|
||||
// 3) basic type "resolution key"
|
||||
// 4) UserType or BasicType class name - directly, or through a TypeDefinition
|
||||
|
||||
if ( name.startsWith( ConverterDescriptor.TYPE_NAME_PREFIX ) ) {
|
||||
return NamedConverterResolution.from(
|
||||
|
@ -534,6 +537,18 @@ public class BasicValue extends SimpleValue implements JdbcTypeDescriptorIndicat
|
|||
);
|
||||
}
|
||||
|
||||
if ( name.startsWith( BasicTypeImpl.EXTERNALIZED_PREFIX ) ) {
|
||||
final BasicTypeImpl<Object> basicType = context.getBootstrapContext().resolveAdHocBasicType( name );
|
||||
|
||||
return new NamedBasicTypeResolution(
|
||||
basicType.getJavaTypeDescriptor(),
|
||||
basicType,
|
||||
null,
|
||||
explicitMutabilityPlanAccess,
|
||||
context
|
||||
);
|
||||
}
|
||||
|
||||
// see if it is a named basic type
|
||||
final BasicType basicTypeByName = typeConfiguration.getBasicTypeRegistry().getRegisteredType( name );
|
||||
if ( basicTypeByName != null ) {
|
||||
|
@ -661,7 +676,7 @@ public class BasicValue extends SimpleValue implements JdbcTypeDescriptorIndicat
|
|||
}
|
||||
|
||||
public void setExplicitTypeName(String typeName) {
|
||||
this.explicitTypeName = typeName;;
|
||||
this.explicitTypeName = typeName;
|
||||
}
|
||||
|
||||
public void setTypeName(String typeName) {
|
||||
|
|
|
@ -19,11 +19,11 @@ import org.hibernate.internal.util.collections.CollectionHelper;
|
|||
import org.hibernate.metamodel.model.convert.spi.BasicValueConverter;
|
||||
import org.hibernate.type.descriptor.java.JavaType;
|
||||
import org.hibernate.type.descriptor.jdbc.JdbcType;
|
||||
import org.hibernate.type.internal.BasicTypeImpl;
|
||||
import org.hibernate.type.internal.ConvertedBasicTypeImpl;
|
||||
import org.hibernate.type.internal.ImmutableConvertedBasicTypeImpl;
|
||||
import org.hibernate.type.internal.ImmutableNamedBasicTypeImpl;
|
||||
import org.hibernate.type.internal.NamedBasicTypeImpl;
|
||||
import org.hibernate.type.internal.BasicTypeImpl;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
import org.hibernate.usertype.UserType;
|
||||
|
||||
|
@ -152,14 +152,26 @@ public class BasicTypeRegistry implements Serializable {
|
|||
}
|
||||
|
||||
/**
|
||||
* Find an existing BasicType registration for the given JavaTypeDescriptor and
|
||||
* SqlTypeDescriptor combo or create (and register) one.
|
||||
* Find an existing BasicType registration for the given JavaType descriptor and
|
||||
* JdbcType descriptor combo or create (and register) one.
|
||||
*/
|
||||
public <J> BasicType<J> resolve(JavaType<J> jtdToUse, JdbcType stdToUse) {
|
||||
return resolve(
|
||||
jtdToUse,
|
||||
stdToUse,
|
||||
() -> new BasicTypeImpl<>( jtdToUse, stdToUse )
|
||||
() -> {
|
||||
final BasicTypeImpl<J> basicType = new BasicTypeImpl<>( jtdToUse, stdToUse );
|
||||
|
||||
// if we are still building mappings, register this ad-hoc type via a
|
||||
// unique code. this is to support envers
|
||||
try {
|
||||
typeConfiguration.getMetadataBuildingContext().getBootstrapContext().registerAdHocBasicType( basicType );
|
||||
}
|
||||
catch (Exception ignore) {
|
||||
}
|
||||
|
||||
return basicType;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ public class SerializableJavaTypeDescriptor<T extends Serializable> extends Abst
|
|||
public JdbcType getRecommendedJdbcType(JdbcTypeDescriptorIndicators indicators) {
|
||||
final int typeCode = indicators.isLob()
|
||||
? Types.BLOB
|
||||
: Types.LONGVARBINARY;
|
||||
: Types.VARBINARY;
|
||||
return indicators.getTypeConfiguration().getJdbcTypeDescriptorRegistry().getDescriptor( typeCode );
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
*/
|
||||
package org.hibernate.type.internal;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import org.hibernate.internal.util.collections.ArrayHelper;
|
||||
import org.hibernate.type.AbstractSingleColumnStandardBasicType;
|
||||
import org.hibernate.type.AdjustableBasicType;
|
||||
|
@ -16,10 +18,23 @@ import org.hibernate.type.descriptor.jdbc.JdbcType;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public class BasicTypeImpl<J> extends AbstractSingleColumnStandardBasicType<J> implements AdjustableBasicType<J> {
|
||||
public static final String EXTERNALIZED_PREFIX = "basicType";
|
||||
public static final String[] NO_REG_KEYS = ArrayHelper.EMPTY_STRING_ARRAY;
|
||||
|
||||
private static int count;
|
||||
|
||||
private final String name;
|
||||
|
||||
public BasicTypeImpl(JavaType<J> jtd, JdbcType std) {
|
||||
super( std, jtd );
|
||||
name = String.format(
|
||||
Locale.ROOT,
|
||||
"%s@%s(%s,%s)",
|
||||
EXTERNALIZED_PREFIX,
|
||||
++count,
|
||||
jtd.getJavaTypeClass().getName(),
|
||||
std.getDefaultSqlTypeCode()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -28,9 +43,31 @@ public class BasicTypeImpl<J> extends AbstractSingleColumnStandardBasicType<J> i
|
|||
return NO_REG_KEYS;
|
||||
}
|
||||
|
||||
/**
|
||||
* BasicTypeImpl produces a name whose sole purpose is to
|
||||
* be used as part of interpreting Envers-produced mappings.
|
||||
* We want to use the same exact BasicTypeImpl *instance* in
|
||||
* the audit mapping (Envers) as is used in the audited (ORM)
|
||||
* mapping.
|
||||
*
|
||||
* The name is in the form {@code `basicType@${u}(${o},${r})`}, where<ol>
|
||||
* <li>${u} is a unique number</li>
|
||||
* <li>${o} is the mapped Java type</li>
|
||||
* <li>${r} is the mapped SQL type (JDBC type code)</li>
|
||||
* </ol>
|
||||
*
|
||||
* {@code `basicType@${u}`} is enough to uniquely identify this type instance;
|
||||
* the Java Type and JDBC type code are informational
|
||||
*
|
||||
* E.g. {@code `basicType@321(java.lang.String,12)`}
|
||||
*/
|
||||
@Override
|
||||
public String getName() {
|
||||
// again, irrelevant
|
||||
return null;
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ import org.hibernate.metamodel.internal.ManagedTypeRepresentationResolverStandar
|
|||
import org.hibernate.metamodel.spi.ManagedTypeRepresentationResolver;
|
||||
import org.hibernate.query.sqm.function.SqmFunctionDescriptor;
|
||||
import org.hibernate.resource.beans.spi.BeanInstanceProducer;
|
||||
import org.hibernate.type.internal.BasicTypeImpl;
|
||||
import org.hibernate.type.spi.TypeConfiguration;
|
||||
|
||||
import org.jboss.jandex.IndexView;
|
||||
|
@ -151,6 +152,15 @@ public class BootstrapContextImpl implements BootstrapContext {
|
|||
return ManagedTypeRepresentationResolverStandard.INSTANCE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerAdHocBasicType(BasicTypeImpl<?> basicType) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> BasicTypeImpl<T> resolveAdHocBasicType(String key) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
delegate.release();
|
||||
|
|
Loading…
Reference in New Issue