HHH-17835 Custom ConvertedPrimitiveBasicTypeImpl type resolution

This commit is contained in:
Marco Belladelli 2024-03-11 22:53:41 +01:00
parent 02298cbc52
commit d6bc041dff
No known key found for this signature in database
GPG Key ID: D1D0C3030AE3AA35
4 changed files with 91 additions and 8 deletions

View File

@ -6,6 +6,7 @@
*/
package org.hibernate.boot.model.process.internal;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.Map;
import java.util.function.Function;
@ -20,6 +21,7 @@ import org.hibernate.mapping.BasicValue;
import org.hibernate.metamodel.mapping.JdbcMapping;
import org.hibernate.type.BasicType;
import org.hibernate.type.descriptor.converter.internal.AttributeConverterMutabilityPlanImpl;
import org.hibernate.type.descriptor.converter.spi.BasicValueConverter;
import org.hibernate.type.descriptor.converter.spi.JpaAttributeConverter;
import org.hibernate.type.descriptor.java.BasicJavaType;
import org.hibernate.type.descriptor.java.ImmutableMutabilityPlan;
@ -28,6 +30,7 @@ import org.hibernate.type.descriptor.java.MutabilityPlan;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.JdbcTypeIndicators;
import org.hibernate.type.internal.CustomMutabilityConvertedBasicTypeImpl;
import org.hibernate.type.internal.CustomMutabilityConvertedPrimitiveBasicTypeImpl;
import org.hibernate.type.spi.TypeConfiguration;
/**
@ -40,6 +43,7 @@ public class NamedConverterResolution<J> implements BasicValue.Resolution<J> {
Function<TypeConfiguration, BasicJavaType> explicitJtdAccess,
Function<TypeConfiguration, JdbcType> explicitStdAccess,
Function<TypeConfiguration, MutabilityPlan> explicitMutabilityPlanAccess,
Type resolvedJavaType,
JdbcTypeIndicators sqlTypeIndicators,
JpaAttributeConverterCreationContext converterCreationContext,
MetadataBuildingContext context) {
@ -48,6 +52,7 @@ public class NamedConverterResolution<J> implements BasicValue.Resolution<J> {
explicitStdAccess,
explicitMutabilityPlanAccess,
converter( converterCreationContext, converterDescriptor ),
resolvedJavaType,
sqlTypeIndicators,
context
);
@ -76,6 +81,7 @@ public class NamedConverterResolution<J> implements BasicValue.Resolution<J> {
explicitStdAccess,
explicitMutabilityPlanAccess,
converter( converterCreationContext, converterDescriptor ),
null,
sqlTypeIndicators,
context
);
@ -93,6 +99,7 @@ public class NamedConverterResolution<J> implements BasicValue.Resolution<J> {
Function<TypeConfiguration, JdbcType> explicitStdAccess,
Function<TypeConfiguration, MutabilityPlan> explicitMutabilityPlanAccess,
JpaAttributeConverter<T,?> converter,
Type resolvedJavaType,
JdbcTypeIndicators sqlTypeIndicators,
MetadataBuildingContext context) {
final TypeConfiguration typeConfiguration = context.getBootstrapContext().getTypeConfiguration();
@ -122,12 +129,18 @@ public class NamedConverterResolution<J> implements BasicValue.Resolution<J> {
domainJtd
);
//noinspection unchecked
final Class<T> primitiveClass = resolvedJavaType instanceof Class<?> && ( (Class<?>) resolvedJavaType ).isPrimitive()
? (Class<T>) resolvedJavaType
: null;
return new NamedConverterResolution<>(
domainJtd,
relationalJtd,
jdbcType,
converter,
mutabilityPlan,
primitiveClass,
context.getBootstrapContext().getTypeConfiguration()
);
}
@ -182,6 +195,7 @@ public class NamedConverterResolution<J> implements BasicValue.Resolution<J> {
JdbcType jdbcType,
JpaAttributeConverter<J,?> valueConverter,
MutabilityPlan<J> mutabilityPlan,
Class<J> primitiveClass,
TypeConfiguration typeConfiguration) {
assert domainJtd != null;
this.domainJtd = domainJtd;
@ -198,7 +212,7 @@ public class NamedConverterResolution<J> implements BasicValue.Resolution<J> {
assert mutabilityPlan != null;
this.mutabilityPlan = mutabilityPlan;
this.legacyResolvedType = new CustomMutabilityConvertedBasicTypeImpl<>(
this.legacyResolvedType = legacyResolvedType(
ConverterDescriptor.TYPE_NAME_PREFIX
+ valueConverter.getConverterJavaType().getJavaType().getTypeName(),
String.format(
@ -208,11 +222,41 @@ public class NamedConverterResolution<J> implements BasicValue.Resolution<J> {
),
jdbcType,
valueConverter,
primitiveClass,
mutabilityPlan
);
this.jdbcMapping = legacyResolvedType;
}
private static <J> BasicType<J> legacyResolvedType(
String name,
String description,
JdbcType jdbcType,
BasicValueConverter<J, ?> converter,
Class<J> primitiveClass,
MutabilityPlan<J> mutabilityPlan) {
if ( primitiveClass != null ) {
assert primitiveClass.isPrimitive();
return new CustomMutabilityConvertedPrimitiveBasicTypeImpl<>(
name,
description,
jdbcType,
converter,
primitiveClass,
mutabilityPlan
);
}
else {
return new CustomMutabilityConvertedBasicTypeImpl<>(
name,
description,
jdbcType,
converter,
mutabilityPlan
);
}
}
@Override
public BasicType<J> getLegacyResolvedBasicType() {
return legacyResolvedType;

View File

@ -665,6 +665,7 @@ public class BasicValue extends SimpleValue implements JdbcTypeIndicators, Resol
explicitJavaTypeAccess,
explicitJdbcTypeAccess,
explicitMutabilityPlanAccess,
resolvedJavaType,
this,
this,
getBuildingContext()

View File

@ -319,17 +319,18 @@ public class AttributeFactory {
);
}
@SuppressWarnings( "unchecked" )
private static <Y> DomainType<Y> basicDomainType(ValueContext typeContext, MetadataContext context) {
if ( typeContext.getJpaBindableType().isPrimitive() ) {
// Special BasicDomainType necessary for primitive types in the JPA metamodel
@SuppressWarnings("unchecked")
final Value hibernateValue = typeContext.getHibernateValue();
if ( typeContext.getJpaBindableType().isPrimitive()
&& ( (SimpleValue) hibernateValue ).getJpaAttributeConverterDescriptor() == null ) {
// Special BasicDomainType necessary for primitive types in the JPA metamodel.
// When a converted is applied to the attribute we already resolve to the correct type
final Class<Y> type = (Class<Y>) typeContext.getJpaBindableType();
return context.resolveBasicType(type);
return context.resolveBasicType( type );
}
else {
@SuppressWarnings("unchecked")
DomainType<Y> type = (DomainType<Y>) typeContext.getHibernateValue().getType();
return type;
return (DomainType<Y>) hibernateValue.getType();
}
}

View File

@ -0,0 +1,37 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
*/
package org.hibernate.type.internal;
import org.hibernate.type.descriptor.converter.spi.BasicValueConverter;
import org.hibernate.type.descriptor.java.MutabilityPlan;
import org.hibernate.type.descriptor.jdbc.JdbcType;
/**
* Wrapper of {@link CustomMutabilityConvertedBasicTypeImpl} for primitive type.
*
* @author Marco Belladelli
*/
public class CustomMutabilityConvertedPrimitiveBasicTypeImpl<J> extends CustomMutabilityConvertedBasicTypeImpl<J> {
private final Class<J> primitiveClass;
public CustomMutabilityConvertedPrimitiveBasicTypeImpl(
String name,
String description,
JdbcType jdbcType,
BasicValueConverter<J, ?> converter,
Class<J> primitiveClass,
MutabilityPlan<J> mutabilityPlan) {
super( name, description, jdbcType, converter, mutabilityPlan );
assert primitiveClass.isPrimitive();
this.primitiveClass = primitiveClass;
}
@Override
public Class<J> getJavaType() {
return primitiveClass;
}
}