diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/AnnotationHelper.java b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/AnnotationHelper.java index be0453f1a487..84bdd534a2d5 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/AnnotationHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/AnnotationHelper.java @@ -4,7 +4,6 @@ */ package org.hibernate.boot.model.internal; -import java.lang.reflect.ParameterizedType; import java.util.HashMap; import org.hibernate.annotations.Parameter; @@ -17,7 +16,7 @@ import org.hibernate.resource.beans.spi.ManagedBean; import org.hibernate.type.BasicType; import org.hibernate.type.CustomType; -import org.hibernate.type.descriptor.converter.internal.JpaAttributeConverterImpl; +import org.hibernate.type.descriptor.converter.spi.JpaAttributeConverter; import org.hibernate.type.descriptor.java.JavaType; import org.hibernate.type.descriptor.java.spi.JavaTypeRegistry; import org.hibernate.type.descriptor.jdbc.JdbcType; @@ -28,9 +27,8 @@ import jakarta.persistence.AttributeConverter; -import static org.hibernate.internal.util.GenericsHelper.extractClass; -import static org.hibernate.internal.util.GenericsHelper.extractParameterizedType; import static org.hibernate.internal.util.collections.CollectionHelper.mapOfSize; +import static org.hibernate.type.descriptor.converter.internal.ConverterHelper.createJpaAttributeConverter; /** * @author Steve Ebersole @@ -38,8 +36,8 @@ public class AnnotationHelper { public static HashMap extractParameterMap(Parameter[] parameters) { final HashMap paramMap = mapOfSize( parameters.length ); - for ( int i = 0; i < parameters.length; i++ ) { - paramMap.put( parameters[i].name(), parameters[i].value() ); + for ( Parameter parameter : parameters ) { + paramMap.put( parameter.name(), parameter.value() ); } return paramMap; } @@ -58,33 +56,21 @@ public static JdbcMapping resolveAttributeConverter( MetadataBuildingContext context) { final BootstrapContext bootstrapContext = context.getBootstrapContext(); final TypeConfiguration typeConfiguration = bootstrapContext.getTypeConfiguration(); - final var bean = bootstrapContext.getManagedBeanRegistry().getBean( type ); - - final ParameterizedType converterParameterizedType = extractParameterizedType( bean.getBeanClass() ); - final Class domainJavaClass = extractClass( converterParameterizedType.getActualTypeArguments()[0] ); - final Class relationalJavaClass = extractClass( converterParameterizedType.getActualTypeArguments()[1] ); - + @SuppressWarnings("unchecked") + final var castBean = (ManagedBean>) bean; final JavaTypeRegistry registry = typeConfiguration.getJavaTypeRegistry(); - final JavaType domainJtd = registry.resolveDescriptor( domainJavaClass ); - final JavaType relationalJtd = registry.resolveDescriptor( relationalJavaClass ); - - final JpaAttributeConverterImpl valueConverter = - new JpaAttributeConverterImpl<>( - (ManagedBean>) bean, - registry.resolveDescriptor( bean.getBeanClass() ), - domainJtd, - relationalJtd - ); + final JpaAttributeConverter valueConverter = createJpaAttributeConverter( castBean, registry ); return new ConvertedBasicTypeImpl<>( ConverterDescriptor.TYPE_NAME_PREFIX + valueConverter.getConverterJavaType().getTypeName(), String.format( "BasicType adapter for AttributeConverter<%s,%s>", - domainJtd.getTypeName(), - relationalJtd.getTypeName() + valueConverter.getDomainJavaType().getTypeName(), + valueConverter.getRelationalJavaType().getTypeName() ), - relationalJtd.getRecommendedJdbcType( typeConfiguration.getCurrentBaseSqlTypeIndicators() ), + registry.resolveDescriptor( valueConverter.getRelationalJavaType().getJavaType() ) + .getRecommendedJdbcType( typeConfiguration.getCurrentBaseSqlTypeIndicators() ), valueConverter ); } diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/process/internal/InferredBasicValueResolution.java b/hibernate-core/src/main/java/org/hibernate/boot/model/process/internal/InferredBasicValueResolution.java index 02944322bbe1..679e167b57c1 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/process/internal/InferredBasicValueResolution.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/process/internal/InferredBasicValueResolution.java @@ -70,7 +70,7 @@ public JdbcType getJdbcType() { @Override @SuppressWarnings("unchecked") public BasicValueConverter getValueConverter() { return updatedType == null - ? jdbcMapping.getValueConverter() + ? (BasicValueConverter) jdbcMapping.getValueConverter() : (BasicValueConverter) updatedType.getValueConverter(); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/JdbcMapping.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/JdbcMapping.java index bdbc96b5213a..77d2720a812f 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/JdbcMapping.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/JdbcMapping.java @@ -102,25 +102,41 @@ default JavaType getJdbcJavaType() { * or null if there is no conversion. */ @Incubating - default BasicValueConverter getValueConverter() { + default BasicValueConverter getValueConverter() { return null; } //TODO: would it be better to just give JdbcMapping a // noop converter by default, instead of having // to deal with null here? - @SuppressWarnings({"rawtypes", "unchecked"}) - default Object convertToRelationalValue(Object value) { - BasicValueConverter valueConverter = getValueConverter(); - return valueConverter == null ? value : valueConverter.toRelationalValue( value ); + default Object convertToRelationalValue(T value) { + final var converter = getValueConverter(); + if ( converter == null ) { + return value; + } + else { + assert value == null + || converter.getDomainJavaType().isInstance( value ); + @SuppressWarnings( "unchecked" ) // safe, we just checked + final var valueConverter = (BasicValueConverter) converter; + return valueConverter.toRelationalValue( value ); + } } - default Object convertToDomainValue(Object value) { - BasicValueConverter valueConverter = getValueConverter(); - return valueConverter == null ? value : valueConverter.toDomainValue( value ); + default Object convertToDomainValue(T value) { + var converter = getValueConverter(); + if ( converter == null ) { + return value; + } + else { + assert value == null + || converter.getRelationalJavaType().isInstance( value ); + @SuppressWarnings( "unchecked" ) // safe, we just checked + final var valueConverter = (BasicValueConverter) converter; + return valueConverter.toDomainValue( value ); + } } - @Override default int getJdbcTypeCount() { return 1; diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddableMappingTypeImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddableMappingTypeImpl.java index 46b2483a9a49..e9eb135a48ec 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddableMappingTypeImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/mapping/internal/EmbeddableMappingTypeImpl.java @@ -871,7 +871,7 @@ protected Object[] getAttributeValues(Object compositeInstance) { ? getValue( compositeInstance, i ) : null; } - results[i] = compositeInstance.getClass().getName(); + results[i] = compositeInstance.getClass(); return results; } } diff --git a/hibernate-core/src/main/java/org/hibernate/query/sqm/function/SelfRenderingFunctionSqlAstExpression.java b/hibernate-core/src/main/java/org/hibernate/query/sqm/function/SelfRenderingFunctionSqlAstExpression.java index f1c3ae2c9376..e0c7af1d9e61 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/sqm/function/SelfRenderingFunctionSqlAstExpression.java +++ b/hibernate-core/src/main/java/org/hibernate/query/sqm/function/SelfRenderingFunctionSqlAstExpression.java @@ -102,7 +102,7 @@ public DomainResult createDomainResult( final BasicValueConverter converter; if ( jdbcMapping != null ) { jdbcJavaType = (JavaType) jdbcMapping.getJdbcJavaType(); - converter = jdbcMapping.getValueConverter(); + converter = (BasicValueConverter) jdbcMapping.getValueConverter(); } else if ( type != null ) { jdbcJavaType = type.getExpressibleJavaType(); diff --git a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/basic/BasicResult.java b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/basic/BasicResult.java index 643d660d6e14..1bba9ceb8ed1 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/results/graph/basic/BasicResult.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/results/graph/basic/BasicResult.java @@ -55,7 +55,8 @@ public BasicResult( jdbcValuesArrayPosition, resultVariable, jdbcMapping.getJavaTypeDescriptor(), - jdbcMapping.getValueConverter(), + (BasicValueConverter) + jdbcMapping.getValueConverter(), navigablePath, coerceResultType, unwrapRowProcessingState diff --git a/hibernate-core/src/main/java/org/hibernate/type/BasicType.java b/hibernate-core/src/main/java/org/hibernate/type/BasicType.java index 1d562e78f497..7e58d2a4c7bf 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/BasicType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/BasicType.java @@ -46,7 +46,7 @@ default MappingType getMappedType() { @Override default JavaType getJavaTypeDescriptor() { - return this.getMappedJavaType(); + return getMappedJavaType(); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/type/CustomType.java b/hibernate-core/src/main/java/org/hibernate/type/CustomType.java index 5b1d38708b07..983e369e4c17 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/CustomType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/CustomType.java @@ -11,6 +11,7 @@ import java.util.Arrays; import java.util.Map; +import jakarta.persistence.AttributeConverter; import org.hibernate.HibernateException; import org.hibernate.MappingException; import org.hibernate.cache.MutableCacheKeyBuilder; @@ -33,6 +34,7 @@ import org.hibernate.usertype.UserVersionType; import static org.hibernate.internal.util.collections.ArrayHelper.EMPTY_STRING_ARRAY; +import static org.hibernate.type.descriptor.converter.internal.ConverterHelper.createValueConverter; /** * Adapts {@link UserType} to the generic {@link Type} interface, in order @@ -62,22 +64,25 @@ public class CustomType private final ValueBinder valueBinder; private final JdbcLiteralFormatter jdbcLiteralFormatter; + private final BasicValueConverter converter; + public CustomType(UserType userType, TypeConfiguration typeConfiguration) throws MappingException { this( userType, EMPTY_STRING_ARRAY, typeConfiguration ); } public CustomType(UserType userType, String[] registrationKeys, TypeConfiguration typeConfiguration) { this.userType = userType; + this.registrationKeys = registrationKeys; name = userType.getClass().getName(); - mappedJavaType = getMappedJavaType( userType ); - final BasicValueConverter converter = userType.getValueConverter(); - if ( converter != null ) { + final AttributeConverter valueConverter = userType.getValueConverter(); + if ( valueConverter != null ) { + converter = createValueConverter( valueConverter, typeConfiguration.getJavaTypeRegistry() ); // When an explicit value converter is given, // we configure the custom type to use that instead of adapters that delegate to UserType. // This is necessary to support selecting a column with multiple domain type representations. - jdbcType = userType.getJdbcType( typeConfiguration ); + jdbcType = typeConfiguration.getJdbcTypeRegistry().getDescriptor( userType.getSqlType() ); jdbcJavaType = converter.getRelationalJavaType(); //noinspection unchecked valueExtractor = (ValueExtractor) jdbcType.getExtractor( jdbcJavaType ); @@ -93,16 +98,17 @@ public CustomType(UserType userType, String[] registrationKeys, TypeConfigura valueExtractor = jdbcType.getExtractor( mappedJavaType ); valueBinder = jdbcType.getBinder( mappedJavaType ); jdbcLiteralFormatter = - userType instanceof EnhancedUserType ? jdbcType.getJdbcLiteralFormatter( mappedJavaType ) : null; + userType instanceof EnhancedUserType + ? jdbcType.getJdbcLiteralFormatter( mappedJavaType ) + : null; + converter = null; } - - this.registrationKeys = registrationKeys; } private JavaType getMappedJavaType(UserType userType) { return userType instanceof UserVersionType userVersionType - ? new UserTypeVersionJavaTypeWrapper<>( userVersionType ) - : new UserTypeJavaTypeWrapper<>( userType ); + ? new UserTypeVersionJavaTypeWrapper<>( userVersionType, this ) + : new UserTypeJavaTypeWrapper<>( userType, this ); } public UserType getUserType() { @@ -166,11 +172,9 @@ public Object assemble(Serializable cached, SharedSessionContractImplementor ses // we have to handle the fact that it could produce a null value, // in which case we will try to use a converter for assembling, // or if that doesn't exist, simply use the relational value as is - if ( assembled == null && cached != null ) { - final BasicValueConverter converter = getUserType().getValueConverter(); - return converter == null ? cached : converter.toDomainValue( cached ); - } - return assembled; + return assembled == null && cached != null + ? convertToDomainValue( cached ) + : assembled; } @Override @@ -189,20 +193,15 @@ private Serializable disassembleForCache(Object value) { // we have to handle the fact that it could produce a null value, // in which case we will try to use a converter for disassembling, // or if that doesn't exist, simply use the domain value as is - if ( disassembled == null ){ - final BasicValueConverter converter = getUserType().getValueConverter(); - return converter == null ? disassembled : (Serializable) converter.toRelationalValue( (J) value ); - } - else { - return disassembled; - } + return disassembled == null + ? (Serializable) convertToRelationalValue( (J) value ) + : disassembled; } @Override public Object disassemble(Object value, SharedSessionContractImplementor session) { // Use the value converter if available for conversion to the jdbc representation - final BasicValueConverter converter = getUserType().getValueConverter(); - return converter == null ? value : converter.toRelationalValue( (J) value ); + return convertToRelationalValue( (J) value ); } @Override @@ -395,8 +394,8 @@ public JavaType getJdbcJavaType() { } @Override - public BasicValueConverter getValueConverter() { - return userType.getValueConverter(); + public BasicValueConverter getValueConverter() { + return converter; } } diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/converter/internal/AttributeConverterWrapper.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/converter/internal/AttributeConverterWrapper.java new file mode 100644 index 000000000000..03e9d12eb6fd --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/converter/internal/AttributeConverterWrapper.java @@ -0,0 +1,100 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.type.descriptor.converter.internal; + +import jakarta.persistence.AttributeConverter; +import jakarta.persistence.PersistenceException; +import org.hibernate.type.descriptor.converter.spi.BasicValueConverter; +import org.hibernate.type.descriptor.java.JavaType; + +/** + * @author Gavin King + * @since 7.0 + */ +public class AttributeConverterWrapper implements BasicValueConverter { + private final AttributeConverter converter; + private final JavaType> converterJtd; + private final JavaType domainJtd; + private final JavaType jdbcJtd; + + public AttributeConverterWrapper( + AttributeConverter converter, + JavaType> converterJtd, + JavaType domainJtd, + JavaType jdbcJtd) { + this.converter = converter; + this.converterJtd = converterJtd; + this.domainJtd = domainJtd; + this.jdbcJtd = jdbcJtd; + } + + @Override + public O toDomainValue(R relationalForm) { + try { + return converter.convertToEntityAttribute( relationalForm ); + } + catch (PersistenceException pe) { + throw pe; + } + catch (RuntimeException re) { + throw new PersistenceException( "Error attempting to apply AttributeConverter", re ); + } + } + + @Override + public R toRelationalValue(O domainForm) { + try { + return converter.convertToDatabaseColumn( domainForm ); + } + catch (PersistenceException pe) { + throw pe; + } + catch (RuntimeException re) { + throw new PersistenceException( "Error attempting to apply AttributeConverter: " + re.getMessage(), re ); + } + } + + @Override + public JavaType getDomainJavaType() { + return domainJtd; + } + + @Override + public JavaType getRelationalJavaType() { + return jdbcJtd; + } + + @Override + public boolean equals(Object o) { + if ( this == o ) { + return true; + } + if ( o == null || getClass() != o.getClass() ) { + return false; + } + + AttributeConverterWrapper that = (AttributeConverterWrapper) o; + + if ( !converter.equals( that.converter ) ) { + return false; + } + if ( !converterJtd.equals( that.converterJtd ) ) { + return false; + } + if ( !domainJtd.equals( that.domainJtd ) ) { + return false; + } + return jdbcJtd.equals( that.jdbcJtd ); + } + + @Override + public int hashCode() { + int result = converter.hashCode(); + result = 31 * result + converterJtd.hashCode(); + result = 31 * result + domainJtd.hashCode(); + result = 31 * result + jdbcJtd.hashCode(); + return result; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/converter/internal/ConverterHelper.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/converter/internal/ConverterHelper.java new file mode 100644 index 000000000000..a1b43707f6d8 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/converter/internal/ConverterHelper.java @@ -0,0 +1,48 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * Copyright Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.type.descriptor.converter.internal; + +import jakarta.persistence.AttributeConverter; +import org.hibernate.resource.beans.spi.ManagedBean; +import org.hibernate.type.descriptor.converter.spi.BasicValueConverter; +import org.hibernate.type.descriptor.converter.spi.JpaAttributeConverter; +import org.hibernate.type.descriptor.java.spi.JavaTypeRegistry; + +import java.lang.reflect.ParameterizedType; + +import static org.hibernate.internal.util.GenericsHelper.extractClass; +import static org.hibernate.internal.util.GenericsHelper.extractParameterizedType; + +/** + * @author Gavin King + * @since 7.0 + */ +public class ConverterHelper { + public static BasicValueConverter createValueConverter( + AttributeConverter converter, JavaTypeRegistry registry) { + final ParameterizedType converterParameterizedType = extractParameterizedType( converter.getClass() ); + final Class domainJavaClass = extractClass( converterParameterizedType.getActualTypeArguments()[0] ); + final Class relationalJavaClass = extractClass( converterParameterizedType.getActualTypeArguments()[1] ); + return new AttributeConverterWrapper<>( + converter, + registry.resolveDescriptor( converter.getClass() ), + registry.resolveDescriptor( domainJavaClass ), + registry.resolveDescriptor( relationalJavaClass ) + ); + } + + public static JpaAttributeConverter createJpaAttributeConverter( + ManagedBean> bean, JavaTypeRegistry registry) { + final ParameterizedType converterParameterizedType = extractParameterizedType( bean.getBeanClass() ); + final Class domainJavaClass = extractClass( converterParameterizedType.getActualTypeArguments()[0] ); + final Class relationalJavaClass = extractClass( converterParameterizedType.getActualTypeArguments()[1] ); + return new JpaAttributeConverterImpl<>( + bean, + registry.resolveDescriptor( bean.getBeanClass() ), + registry.resolveDescriptor( domainJavaClass ), + registry.resolveDescriptor( relationalJavaClass ) + ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/BigDecimalJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/BigDecimalJavaType.java index 815433aeb51b..8accc2bf5555 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/BigDecimalJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/BigDecimalJavaType.java @@ -32,6 +32,11 @@ public BigDecimal fromString(CharSequence string) { return new BigDecimal( string.toString() ); } + @Override + public boolean isInstance(Object value) { + return value instanceof BigDecimal; + } + @Override public boolean areEqual(BigDecimal one, BigDecimal another) { return one == another diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/BigIntegerJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/BigIntegerJavaType.java index 272109c14066..5f9eae0892c6 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/BigIntegerJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/BigIntegerJavaType.java @@ -34,6 +34,11 @@ public BigInteger fromString(CharSequence string) { return new BigInteger( string.toString() ); } + @Override + public boolean isInstance(Object value) { + return value instanceof BigInteger; + } + @Override public int extractHashCode(BigInteger value) { return value.intValue(); diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/BlobJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/BlobJavaType.java index 714cf7facd3b..22a6c5ed834c 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/BlobJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/BlobJavaType.java @@ -65,6 +65,11 @@ public BlobJavaType() { super( Blob.class, BlobMutabilityPlan.INSTANCE, IncomparableComparator.INSTANCE ); } + @Override + public boolean isInstance(Object value) { + return value instanceof Blob; + } + @Override public String extractLoggableRepresentation(Blob value) { return value == null ? "null" : "{blob}"; diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/BooleanJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/BooleanJavaType.java index 6e7fb1ff9c93..aa87d03be33d 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/BooleanJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/BooleanJavaType.java @@ -60,6 +60,11 @@ public Boolean fromString(CharSequence string) { return Boolean.valueOf( string.toString() ); } + @Override + public boolean isInstance(Object value) { + return value instanceof Boolean; + } + @Override public Boolean fromEncodedString(CharSequence charSequence, int start, int end) { switch ( charSequence.charAt( start ) ) { diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/BooleanPrimitiveArrayJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/BooleanPrimitiveArrayJavaType.java index d9375fc4c5b1..c955f68a49cc 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/BooleanPrimitiveArrayJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/BooleanPrimitiveArrayJavaType.java @@ -36,6 +36,11 @@ protected BooleanPrimitiveArrayJavaType(JavaType baseDescriptor) { super( boolean[].class, baseDescriptor, new ArrayMutabilityPlan() ); } + @Override + public boolean isInstance(Object value) { + return value instanceof boolean[]; + } + @Override public String extractLoggableRepresentation(boolean[] value) { return value == null ? super.extractLoggableRepresentation( null ) : Arrays.toString( value ); diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ByteArrayJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ByteArrayJavaType.java index 5e976d7b909e..07dd4e4c7b7c 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ByteArrayJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ByteArrayJavaType.java @@ -32,11 +32,18 @@ public class ByteArrayJavaType extends AbstractClassJavaType { public ByteArrayJavaType() { super( Byte[].class, ImmutableObjectArrayMutabilityPlan.get(), IncomparableComparator.INSTANCE ); } + + @Override + public boolean isInstance(Object value) { + return value instanceof byte[]; + } + @Override public boolean areEqual(Byte[] one, Byte[] another) { return one == another || one != null && another != null && Arrays.equals(one, another); } + @Override public int extractHashCode(Byte[] bytes) { int hashCode = 1; diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ByteJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ByteJavaType.java index da55c3032ec5..1052f2a58d3f 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ByteJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ByteJavaType.java @@ -44,6 +44,11 @@ public Byte fromString(CharSequence string) { return Byte.valueOf( string.toString() ); } + @Override + public boolean isInstance(Object value) { + return value instanceof Byte; + } + @SuppressWarnings("unchecked") @Override public X unwrap(Byte value, Class type, WrapperOptions options) { diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/CharacterArrayJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/CharacterArrayJavaType.java index 25bb917a0672..61bdf589bb64 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/CharacterArrayJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/CharacterArrayJavaType.java @@ -32,6 +32,11 @@ public CharacterArrayJavaType() { super( Character[].class, ImmutableObjectArrayMutabilityPlan.get(), IncomparableComparator.INSTANCE ); } + @Override + public boolean isInstance(Object value) { + return value instanceof Character[]; + } + @Override public String toString(Character[] value) { return new String( unwrapChars( value ) ); diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/CharacterJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/CharacterJavaType.java index f71199ee0106..fe16e90592cc 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/CharacterJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/CharacterJavaType.java @@ -40,6 +40,11 @@ public Character fromString(CharSequence string) { return string.charAt( 0 ); } + @Override + public boolean isInstance(Object value) { + return value instanceof Character; + } + @SuppressWarnings("unchecked") @Override public X unwrap(Character value, Class type, WrapperOptions options) { diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ClassJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ClassJavaType.java index 3100ae59a52a..02c0e203681a 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ClassJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ClassJavaType.java @@ -21,6 +21,11 @@ public ClassJavaType() { super( (Class) Class.class ); } + @Override + public boolean isInstance(Object value) { + return value instanceof Class; + } + @Override public boolean useObjectEqualsHashCode() { return true; diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ClobJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ClobJavaType.java index fe80242e8a88..398d7ee68491 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ClobJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ClobJavaType.java @@ -47,6 +47,11 @@ public JdbcType getRecommendedJdbcType(JdbcTypeIndicators indicators) { : super.getRecommendedJdbcType( indicators ); } + @Override + public boolean isInstance(Object value) { + return value instanceof Clob; + } + @Override public String extractLoggableRepresentation(Clob value) { return value == null ? "null" : "{clob}"; diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/CurrencyJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/CurrencyJavaType.java index 2bda93c04e65..a2fa030de8fb 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/CurrencyJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/CurrencyJavaType.java @@ -22,6 +22,11 @@ public CurrencyJavaType() { super( Currency.class ); } + @Override + public boolean isInstance(Object value) { + return value instanceof Currency; + } + @Override public boolean useObjectEqualsHashCode() { return true; diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/DateJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/DateJavaType.java index 1157578d10ce..430a8664a5f8 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/DateJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/DateJavaType.java @@ -43,6 +43,11 @@ public DateJavaType() { super( Date.class, DateMutabilityPlan.INSTANCE ); } + @Override + public boolean isInstance(Object value) { + return value instanceof Date; + } + @Override public TemporalType getPrecision() { return TemporalType.TIMESTAMP; diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/DoubleJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/DoubleJavaType.java index a7a06c7dcf5c..3901cb158e5b 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/DoubleJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/DoubleJavaType.java @@ -48,6 +48,11 @@ public Double fromString(CharSequence string) { return Double.valueOf( string.toString() ); } + @Override + public boolean isInstance(Object value) { + return value instanceof Double; + } + @SuppressWarnings("unchecked") @Override public X unwrap(Double value, Class type, WrapperOptions options) { diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/DoublePrimitiveArrayJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/DoublePrimitiveArrayJavaType.java index 3def1d5e1894..8317b4caf391 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/DoublePrimitiveArrayJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/DoublePrimitiveArrayJavaType.java @@ -36,6 +36,11 @@ protected DoublePrimitiveArrayJavaType(JavaType baseDescriptor) { super( double[].class, baseDescriptor, new ArrayMutabilityPlan() ); } + @Override + public boolean isInstance(Object value) { + return value instanceof double[]; + } + @Override public String extractLoggableRepresentation(double[] value) { return value == null ? super.extractLoggableRepresentation( null ) : Arrays.toString( value ); diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/DurationJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/DurationJavaType.java index 2ab2adefb334..8d6f8d23f9ca 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/DurationJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/DurationJavaType.java @@ -43,6 +43,11 @@ public DurationJavaType() { super( Duration.class, ImmutableMutabilityPlan.instance() ); } + @Override + public boolean isInstance(Object value) { + return value instanceof Duration; + } + @Override public JdbcType getRecommendedJdbcType(JdbcTypeIndicators context) { return context.getTypeConfiguration() diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/FloatJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/FloatJavaType.java index c265fd8a4c66..aec3e11d7e0a 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/FloatJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/FloatJavaType.java @@ -47,6 +47,11 @@ public Float fromString(CharSequence string) { return Float.valueOf( string.toString() ); } + @Override + public boolean isInstance(Object value) { + return value instanceof Float; + } + @SuppressWarnings("unchecked") @Override public X unwrap(Float value, Class type, WrapperOptions options) { diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/FloatPrimitiveArrayJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/FloatPrimitiveArrayJavaType.java index 88a748538626..ad795cea243f 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/FloatPrimitiveArrayJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/FloatPrimitiveArrayJavaType.java @@ -36,6 +36,11 @@ protected FloatPrimitiveArrayJavaType(JavaType baseDescriptor) { super( float[].class, baseDescriptor, new ArrayMutabilityPlan() ); } + @Override + public boolean isInstance(Object value) { + return value instanceof float[]; + } + @Override public String extractLoggableRepresentation(float[] value) { return value == null ? super.extractLoggableRepresentation( null ) : Arrays.toString( value ); diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/InstantJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/InstantJavaType.java index 2bf123afbd54..3d1b49220345 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/InstantJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/InstantJavaType.java @@ -42,6 +42,11 @@ public InstantJavaType() { super( Instant.class, ImmutableMutabilityPlan.instance() ); } + @Override + public boolean isInstance(Object value) { + return value instanceof Instant; + } + @Override public TemporalType getPrecision() { return TemporalType.TIMESTAMP; diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/IntegerJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/IntegerJavaType.java index c14c95bfd2bb..cd83479a604b 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/IntegerJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/IntegerJavaType.java @@ -44,6 +44,11 @@ public Integer fromString(CharSequence string) { return string == null ? null : Integer.valueOf( string.toString() ); } + @Override + public boolean isInstance(Object value) { + return value instanceof Integer; + } + @SuppressWarnings("unchecked") @Override public X unwrap(Integer value, Class type, WrapperOptions options) { diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/IntegerPrimitiveArrayJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/IntegerPrimitiveArrayJavaType.java index cb4b7e092968..693a60a5e0f4 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/IntegerPrimitiveArrayJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/IntegerPrimitiveArrayJavaType.java @@ -36,6 +36,11 @@ protected IntegerPrimitiveArrayJavaType(JavaType baseDescriptor) { super( int[].class, baseDescriptor, new ArrayMutabilityPlan() ); } + @Override + public boolean isInstance(Object value) { + return value instanceof int[]; + } + @Override public String extractLoggableRepresentation(int[] value) { return value == null ? super.extractLoggableRepresentation( null ) : Arrays.toString( value ); diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/LocalDateJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/LocalDateJavaType.java index d5e46ebb4563..2ace6939351f 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/LocalDateJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/LocalDateJavaType.java @@ -39,6 +39,11 @@ public LocalDateJavaType() { super( LocalDate.class, ImmutableMutabilityPlan.instance() ); } + @Override + public boolean isInstance(Object value) { + return value instanceof LocalDate; + } + @Override public TemporalType getPrecision() { return TemporalType.DATE; diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/LocalDateTimeJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/LocalDateTimeJavaType.java index 810ce18c9cad..1a6abfdbf8e1 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/LocalDateTimeJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/LocalDateTimeJavaType.java @@ -40,6 +40,11 @@ public LocalDateTimeJavaType() { super( LocalDateTime.class, ImmutableMutabilityPlan.instance() ); } + @Override + public boolean isInstance(Object value) { + return value instanceof LocalDateTime; + } + @Override public TemporalType getPrecision() { return TemporalType.TIMESTAMP; diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/LocalTimeJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/LocalTimeJavaType.java index 3b33e4d81edf..9a1076dd7701 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/LocalTimeJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/LocalTimeJavaType.java @@ -44,6 +44,11 @@ public LocalTimeJavaType() { super( LocalTime.class, ImmutableMutabilityPlan.instance() ); } + @Override + public boolean isInstance(Object value) { + return value instanceof LocalTime; + } + @Override public TemporalType getPrecision() { return TemporalType.TIME; diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/LocaleJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/LocaleJavaType.java index 7297ef3ccbce..47dfa393fa37 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/LocaleJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/LocaleJavaType.java @@ -29,6 +29,11 @@ public LocaleJavaType() { super( Locale.class, ImmutableMutabilityPlan.instance(), LocaleComparator.INSTANCE ); } + @Override + public boolean isInstance(Object value) { + return value instanceof Locale; + } + @Override public boolean useObjectEqualsHashCode() { return true; diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/LongJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/LongJavaType.java index 7ecd256bd692..b44b0c871672 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/LongJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/LongJavaType.java @@ -44,6 +44,11 @@ public Long fromString(CharSequence string) { return Long.valueOf( string.toString() ); } + @Override + public boolean isInstance(Object value) { + return value instanceof Long; + } + @SuppressWarnings("unchecked") @Override public X unwrap(Long value, Class type, WrapperOptions options) { diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/LongPrimitiveArrayJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/LongPrimitiveArrayJavaType.java index d78e1586797e..5331dc3f59b1 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/LongPrimitiveArrayJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/LongPrimitiveArrayJavaType.java @@ -36,6 +36,11 @@ protected LongPrimitiveArrayJavaType(JavaType baseDescriptor) { super( long[].class, baseDescriptor, new ArrayMutabilityPlan() ); } + @Override + public boolean isInstance(Object value) { + return value instanceof long[]; + } + @Override public String extractLoggableRepresentation(long[] value) { return value == null ? super.extractLoggableRepresentation( null ) : Arrays.toString( value ); diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/NClobJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/NClobJavaType.java index 4f824e1638fe..cfff735f39c5 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/NClobJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/NClobJavaType.java @@ -56,6 +56,11 @@ public NClobJavaType() { super( NClob.class, NClobMutabilityPlan.INSTANCE, IncomparableComparator.INSTANCE ); } + @Override + public boolean isInstance(Object value) { + return value instanceof NClob; + } + @Override public String extractLoggableRepresentation(NClob value) { return value == null ? "null" : "{nclob}"; diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ObjectArrayJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ObjectArrayJavaType.java index d17beee65c20..651f3bd1cab1 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ObjectArrayJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ObjectArrayJavaType.java @@ -24,6 +24,11 @@ public ObjectArrayJavaType(JavaType[] components) { this.components = components; } + @Override + public boolean isInstance(Object value) { + return value instanceof Object[]; + } + @Override public String toString(Object[] value) { final StringBuilder sb = new StringBuilder(); diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ObjectJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ObjectJavaType.java index 2e7501e80d71..885e227a1cad 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ObjectJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ObjectJavaType.java @@ -24,6 +24,11 @@ public boolean useObjectEqualsHashCode() { return true; } + @Override + public boolean isInstance(Object value) { + return true; + } + @Override public X unwrap(Object value, Class type, WrapperOptions options) { //noinspection unchecked diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/OffsetDateTimeJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/OffsetDateTimeJavaType.java index cec90437010d..8e8b36cc1d29 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/OffsetDateTimeJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/OffsetDateTimeJavaType.java @@ -63,6 +63,11 @@ public OffsetDateTimeJavaType() { super( OffsetDateTime.class, ImmutableMutabilityPlan.instance(), OffsetDateTime.timeLineOrder() ); } + @Override + public boolean isInstance(Object value) { + return value instanceof OffsetDateTime; + } + @Override public TemporalType getPrecision() { return TemporalType.TIMESTAMP; diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/OffsetTimeJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/OffsetTimeJavaType.java index 1fc1d7939316..7d32af5f59ab 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/OffsetTimeJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/OffsetTimeJavaType.java @@ -43,6 +43,11 @@ public OffsetTimeJavaType() { super( OffsetTime.class, ImmutableMutabilityPlan.instance() ); } + @Override + public boolean isInstance(Object value) { + return value instanceof OffsetTime; + } + @Override public TemporalType getPrecision() { return TemporalType.TIME; diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/PrimitiveByteArrayJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/PrimitiveByteArrayJavaType.java index 7cf9392e6bc4..f0e41b167df6 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/PrimitiveByteArrayJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/PrimitiveByteArrayJavaType.java @@ -32,6 +32,11 @@ public PrimitiveByteArrayJavaType() { super( byte[].class, new ArrayMutabilityPlan(), RowVersionComparator.INSTANCE ); } + @Override + public boolean isInstance(Object value) { + return value instanceof byte[]; + } + @Override public boolean areEqual(byte[] one, byte[] another) { return one == another diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/PrimitiveCharacterArrayJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/PrimitiveCharacterArrayJavaType.java index 22aede16e123..33ccf0bcf506 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/PrimitiveCharacterArrayJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/PrimitiveCharacterArrayJavaType.java @@ -35,6 +35,11 @@ public char[] fromString(CharSequence string) { return string.toString().toCharArray(); } + @Override + public boolean isInstance(Object value) { + return value instanceof char[]; + } + @Override public boolean areEqual(char[] one, char[] another) { return one == another diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/SerializableJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/SerializableJavaType.java index 6180a33f84d4..23c84010359d 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/SerializableJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/SerializableJavaType.java @@ -59,6 +59,11 @@ private static MutabilityPlan createMutabilityPlan(Class type) { return (MutabilityPlan) SerializableMutabilityPlan.INSTANCE; } + @Override + public boolean isInstance(Object value) { + return value instanceof Serializable; + } + @Override public JdbcType getRecommendedJdbcType(JdbcTypeIndicators indicators) { final int typeCode = indicators.isLob() diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ShortJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ShortJavaType.java index 847e1a64eb9a..bfcb09054837 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ShortJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ShortJavaType.java @@ -43,6 +43,11 @@ public Short fromString(CharSequence string) { return Short.valueOf( string.toString() ); } + @Override + public boolean isInstance(Object value) { + return value instanceof Short; + } + @Override public boolean isWider(JavaType javaType) { return switch ( javaType.getTypeName() ) { diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ShortPrimitiveArrayJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ShortPrimitiveArrayJavaType.java index 1665aab28981..05175ddba8de 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ShortPrimitiveArrayJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ShortPrimitiveArrayJavaType.java @@ -36,6 +36,11 @@ protected ShortPrimitiveArrayJavaType(JavaType baseDescriptor) { super( short[].class, baseDescriptor, new ArrayMutabilityPlan() ); } + @Override + public boolean isInstance(Object value) { + return value instanceof short[]; + } + @Override public String extractLoggableRepresentation(short[] value) { return value == null ? super.extractLoggableRepresentation( null ) : Arrays.toString( value ); diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/StringJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/StringJavaType.java index c16002afdf16..5248e33ccbe9 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/StringJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/StringJavaType.java @@ -45,6 +45,11 @@ public String fromString(CharSequence string) { return string.toString(); } + @Override + public boolean isInstance(Object value) { + return value instanceof String; + } + @Override public JdbcType getRecommendedJdbcType(JdbcTypeIndicators stdIndicators) { final TypeConfiguration typeConfiguration = stdIndicators.getTypeConfiguration(); diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/TimeZoneJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/TimeZoneJavaType.java index ee0fc93661d6..3dbc3133724f 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/TimeZoneJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/TimeZoneJavaType.java @@ -29,6 +29,11 @@ public TimeZoneJavaType() { super( TimeZone.class, ImmutableMutabilityPlan.instance(), TimeZoneComparator.INSTANCE ); } + @Override + public boolean isInstance(Object value) { + return value instanceof TimeZone; + } + @Override public boolean useObjectEqualsHashCode() { return true; diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/UUIDJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/UUIDJavaType.java index b550b52fd107..b8d0462f81b7 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/UUIDJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/UUIDJavaType.java @@ -27,6 +27,11 @@ public UUIDJavaType() { super( UUID.class ); } + @Override + public boolean isInstance(Object value) { + return value instanceof UUID; + } + @Override public JdbcType getRecommendedJdbcType(JdbcTypeIndicators context) { return context.getJdbcType( context.getPreferredSqlTypeCodeForUuid() ); diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/UrlJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/UrlJavaType.java index 4cec14a10797..c111905a754a 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/UrlJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/UrlJavaType.java @@ -24,6 +24,11 @@ public UrlJavaType() { super( URL.class ); } + @Override + public boolean isInstance(Object value) { + return value instanceof URL; + } + @Override public JdbcType getRecommendedJdbcType(JdbcTypeIndicators context) { return context.getJdbcType( SqlTypes.VARCHAR ); diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/YearJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/YearJavaType.java index a391638e5270..732d6b910d61 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/YearJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/YearJavaType.java @@ -23,6 +23,11 @@ public YearJavaType() { super( Year.class ); } + @Override + public boolean isInstance(Object value) { + return value instanceof Year; + } + @Override public JdbcType getRecommendedJdbcType(JdbcTypeIndicators context) { return context.getJdbcType( Types.INTEGER ); diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ZoneIdJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ZoneIdJavaType.java index e7ba3f827517..da51b52bf2e9 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ZoneIdJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ZoneIdJavaType.java @@ -24,6 +24,11 @@ public ZoneIdJavaType() { super( ZoneId.class ); } + @Override + public boolean isInstance(Object value) { + return value instanceof ZoneId; + } + @Override public JdbcType getRecommendedJdbcType(JdbcTypeIndicators indicators) { return indicators.getJdbcType( Types.VARCHAR ); diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ZoneOffsetJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ZoneOffsetJavaType.java index 72a126dd59e7..ba78dba8a58c 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ZoneOffsetJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ZoneOffsetJavaType.java @@ -32,6 +32,11 @@ public ZoneOffsetJavaType() { super( ZoneOffset.class, ImmutableMutabilityPlan.instance(), ZoneOffsetComparator.INSTANCE ); } + @Override + public boolean isInstance(Object value) { + return value instanceof ZoneOffset; + } + @Override public boolean useObjectEqualsHashCode() { return true; diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ZonedDateTimeJavaType.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ZonedDateTimeJavaType.java index d17661d6132c..22cde050e664 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ZonedDateTimeJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/java/ZonedDateTimeJavaType.java @@ -42,6 +42,11 @@ public ZonedDateTimeJavaType() { super( ZonedDateTime.class, ImmutableMutabilityPlan.instance(), ZonedDateTimeComparator.INSTANCE ); } + @Override + public boolean isInstance(Object value) { + return value instanceof ZonedDateTime; + } + @Override public TemporalType getPrecision() { return TemporalType.TIMESTAMP; diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/JsonHelper.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/JsonHelper.java index e6bd54878626..562249a97197 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/JsonHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/JsonHelper.java @@ -118,29 +118,31 @@ private static void toString( appender.append( "\":" ); toString( attributeMapping.getMappedType(), values[i], options, appender ); } - else if ( attributeMapping instanceof EmbeddedAttributeMapping ) { + else if ( attributeMapping instanceof EmbeddedAttributeMapping embeddedAttributeMapping ) { if ( values[i] == null ) { - // Skipping the update of the separator is on purpose + // Skipping the update of the separator on purpose continue; } - final EmbeddableMappingType mappingType = (EmbeddableMappingType) attributeMapping.getMappedType(); - final SelectableMapping aggregateMapping = mappingType.getAggregateMapping(); - if ( aggregateMapping == null ) { - toString( - mappingType, - options, - appender, - values[i], - separator - ); - } else { - final String name = aggregateMapping.getSelectableName(); - appender.append( separator ); - appender.append( '"' ); - appender.append( name ); - appender.append( "\":" ); - toString( mappingType, values[i], options, appender ); + final EmbeddableMappingType mappingType = embeddedAttributeMapping.getMappedType(); + final SelectableMapping aggregateMapping = mappingType.getAggregateMapping(); + if ( aggregateMapping == null ) { + toString( + mappingType, + options, + appender, + values[i], + separator + ); + } + else { + final String name = aggregateMapping.getSelectableName(); + appender.append( separator ); + appender.append( '"' ); + appender.append( name ); + appender.append( "\":" ); + toString( mappingType, values[i], options, appender ); + } } } else { @@ -157,9 +159,7 @@ private static void toString(MappingType mappedType, Object value, WrapperOption else if ( mappedType instanceof EmbeddableMappingType embeddableMappingType ) { toString( embeddableMappingType, value, options, appender ); } - else if ( mappedType instanceof BasicType ) { - //noinspection unchecked - final BasicType basicType = (BasicType) mappedType; + else if ( mappedType instanceof BasicType basicType ) { convertedBasicValueToString( basicType.convertToRelationalValue( value ), options, appender, basicType ); } else { @@ -167,8 +167,8 @@ else if ( mappedType instanceof BasicType ) { } } - private static void convertedValueToString( - JavaType javaType, + private static void convertedValueToString( + JavaType javaType, JdbcType jdbcType, Object value, WrapperOptions options, @@ -180,31 +180,41 @@ else if ( jdbcType instanceof AggregateJdbcType aggregateJdbcType ) { toString( aggregateJdbcType.getEmbeddableMappingType(), value, options, appender ); } else { - convertedBasicValueToString( value, options, appender, javaType, jdbcType ); + convertedCastBasicValueToString( value, options, appender, javaType, jdbcType ); } } - private static void convertedBasicValueToString( + private static void convertedBasicValueToString( Object value, WrapperOptions options, JsonAppender appender, - BasicType basicType) { - //noinspection unchecked - convertedBasicValueToString( + BasicType basicType) { + convertedCastBasicValueToString( value, options, appender, - (JavaType) basicType.getJdbcJavaType(), + basicType.getJdbcJavaType(), basicType.getJdbcType() ); } - private static void convertedBasicValueToString( + private static void convertedCastBasicValueToString( Object value, WrapperOptions options, JsonAppender appender, - JavaType javaType, + JavaType javaType, + JdbcType jdbcType) { + assert javaType.isInstance( value ); + //noinspection unchecked + convertedBasicValueToString( (T) value, options, appender, javaType, jdbcType ); + } + + private static void convertedBasicValueToString( + T value, + WrapperOptions options, + JsonAppender appender, + JavaType javaType, JdbcType jdbcType) { switch ( jdbcType.getDefaultSqlTypeCode() ) { case SqlTypes.TINYINT: @@ -316,13 +326,12 @@ private static void convertedBasicValueToString( final int length = Array.getLength( value ); appender.append( '[' ); if ( length != 0 ) { - //noinspection unchecked - final JavaType elementJavaType = ( (BasicPluralJavaType) javaType ).getElementJavaType(); + final JavaType elementJavaType = ( (BasicPluralJavaType) javaType ).getElementJavaType(); final JdbcType elementJdbcType = ( (ArrayJdbcType) jdbcType ).getElementJdbcType(); - Object arrayElement = Array.get( value, 0 ); - convertedValueToString( elementJavaType, elementJdbcType, arrayElement, options, appender ); + final Object firstArrayElement = Array.get( value, 0 ); + convertedValueToString( elementJavaType, elementJdbcType, firstArrayElement, options, appender ); for ( int i = 1; i < length; i++ ) { - arrayElement = Array.get( value, i ); + final Object arrayElement = Array.get( value, i ); appender.append( ',' ); convertedValueToString( elementJavaType, elementJdbcType, arrayElement, options, appender ); } diff --git a/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/StructHelper.java b/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/StructHelper.java index 070fd870efcf..ec323d067547 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/StructHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/StructHelper.java @@ -284,29 +284,49 @@ else if ( attributeMapping instanceof EmbeddableValuedModelPart embeddableValued final JdbcMapping jdbcMapping = attributeMapping.getSingleJdbcMapping(); final Object relationalValue = jdbcMapping.convertToRelationalValue( attributeValues[attributeIndex] ); if ( relationalValue != null ) { - //noinspection rawtypes - final JavaType javaType = jdbcMapping.getJdbcJavaType(); - // Regardless how LOBs are bound by default, through structs we must use the native types - jdbcValues[jdbcIndex] = switch ( jdbcMapping.getJdbcType().getDefaultSqlTypeCode() ) { - case SqlTypes.BLOB, SqlTypes.MATERIALIZED_BLOB -> - //noinspection unchecked - javaType.unwrap( relationalValue, Blob.class, options ); - case SqlTypes.CLOB, SqlTypes.MATERIALIZED_CLOB -> - //noinspection unchecked - javaType.unwrap( relationalValue, Clob.class, options ); - case SqlTypes.NCLOB, SqlTypes.MATERIALIZED_NCLOB -> - //noinspection unchecked - javaType.unwrap( relationalValue, NClob.class, options ); - default -> - //noinspection unchecked - jdbcValues[jdbcIndex] = - jdbcMapping.getJdbcValueBinder().getBindValue( relationalValue, options ); - }; + final JavaType javaType = jdbcMapping.getJdbcJavaType(); + injectCastJdbcValue( jdbcValues, jdbcIndex, options, jdbcMapping, javaType, relationalValue ); } } return jdbcValueCount; } + private static void injectCastJdbcValue( + Object[] jdbcValues, + int jdbcIndex, + WrapperOptions options, + JdbcMapping jdbcMapping, + JavaType javaType, + Object relationalValue) + throws SQLException { + assert javaType.isInstance( relationalValue ); + //noinspection unchecked + injectJdbcValue( jdbcValues, jdbcIndex, options, jdbcMapping, javaType, (T) relationalValue ); + } + + private static void injectJdbcValue( + Object[] jdbcValues, + int jdbcIndex, + WrapperOptions options, + JdbcMapping jdbcMapping, + JavaType javaType, + T relationalValue) + throws SQLException { + // Regardless how LOBs are bound by default, through structs we must use the native types + jdbcValues[jdbcIndex] = switch ( jdbcMapping.getJdbcType().getDefaultSqlTypeCode() ) { + case SqlTypes.BLOB, SqlTypes.MATERIALIZED_BLOB -> + javaType.unwrap( relationalValue, Blob.class, options ); + case SqlTypes.CLOB, SqlTypes.MATERIALIZED_CLOB -> + javaType.unwrap( relationalValue, Clob.class, options ); + case SqlTypes.NCLOB, SqlTypes.MATERIALIZED_NCLOB -> + javaType.unwrap( relationalValue, NClob.class, options ); + default -> + //noinspection unchecked + jdbcValues[jdbcIndex] = + jdbcMapping.getJdbcValueBinder().getBindValue( relationalValue, options ); + }; + } + /** * The sourceJdbcValues array is ordered according to the expected physical order, * as given through the argument order of @Instantiator. diff --git a/hibernate-core/src/main/java/org/hibernate/type/internal/UserTypeJavaTypeWrapper.java b/hibernate-core/src/main/java/org/hibernate/type/internal/UserTypeJavaTypeWrapper.java index 594ce5ec6174..7bc589fb4fdd 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/internal/UserTypeJavaTypeWrapper.java +++ b/hibernate-core/src/main/java/org/hibernate/type/internal/UserTypeJavaTypeWrapper.java @@ -10,10 +10,12 @@ import org.hibernate.SharedSessionContract; import org.hibernate.annotations.Immutable; import org.hibernate.dialect.Dialect; +import org.hibernate.type.CustomType; import org.hibernate.type.descriptor.converter.spi.BasicValueConverter; import org.hibernate.type.descriptor.WrapperOptions; import org.hibernate.type.descriptor.java.BasicJavaType; import org.hibernate.type.descriptor.java.ImmutableMutabilityPlan; +import org.hibernate.type.descriptor.java.JavaType; import org.hibernate.type.descriptor.java.MutabilityPlan; import org.hibernate.type.descriptor.java.MutabilityPlanExposer; import org.hibernate.type.descriptor.jdbc.JdbcType; @@ -29,40 +31,36 @@ public class UserTypeJavaTypeWrapper implements BasicJavaType { protected final UserType userType; private final MutabilityPlan mutabilityPlan; + private final CustomType customType; private final Comparator comparator; - public UserTypeJavaTypeWrapper(UserType userType) { + public UserTypeJavaTypeWrapper(UserType userType, CustomType customType) { this.userType = userType; - - MutabilityPlan resolvedMutabilityPlan = null; - - if ( userType instanceof MutabilityPlanExposer ) { + mutabilityPlan = resolveMutabilityPlan( userType ); + this.customType = customType; + if ( userType instanceof Comparator ) { //noinspection unchecked - resolvedMutabilityPlan = ( (MutabilityPlanExposer) userType ).getExposedMutabilityPlan(); - } - - if ( resolvedMutabilityPlan == null ) { - final Class jClass = userType.returnedClass(); - if ( jClass != null ) { - if ( jClass.getAnnotation( Immutable.class ) != null ) { - resolvedMutabilityPlan = ImmutableMutabilityPlan.instance(); - } - } + comparator = ( (Comparator) userType ); } - - if ( resolvedMutabilityPlan == null ) { - resolvedMutabilityPlan = new MutabilityPlanWrapper<>( userType ); + else { + comparator = this::compare; } + } - this.mutabilityPlan = resolvedMutabilityPlan; - - if ( userType instanceof Comparator ) { + private MutabilityPlan resolveMutabilityPlan(UserType userType) { + if ( userType instanceof MutabilityPlanExposer ) { //noinspection unchecked - this.comparator = ( (Comparator) userType ); + return ( (MutabilityPlanExposer) userType).getExposedMutabilityPlan(); } else { - this.comparator = this::compare; + final Class jClass = userType.returnedClass(); + if ( jClass != null && jClass.getAnnotation( Immutable.class ) != null ) { + return ImmutableMutabilityPlan.instance(); + } + else { + return new MutabilityPlanWrapper( userType ); + } } } @@ -79,7 +77,7 @@ public MutabilityPlan getMutabilityPlan() { @Override public JdbcType getRecommendedJdbcType(JdbcTypeIndicators context) { - return userType.getJdbcType( context.getTypeConfiguration() ); + return context.getJdbcType( userType.getSqlType() ); } @Override @@ -130,10 +128,16 @@ public String toString(J value) { @Override public X unwrap(J value, Class type, WrapperOptions options) { - final BasicValueConverter converter = userType.getValueConverter(); + return unwrap( value, type, customType.getValueConverter(), options ); + } + + private X unwrap(J value, Class type, BasicValueConverter converter, WrapperOptions options) { if ( value != null && !type.isInstance( value ) && converter != null ) { - final Object relationalValue = converter.toRelationalValue( value ); - return converter.getRelationalJavaType().unwrap( relationalValue, type, options ); + final Object relationalValue = customType.convertToRelationalValue( value ); + final JavaType relationalJavaType = converter.getRelationalJavaType(); + assert relationalJavaType.isInstance( relationalValue ); + //noinspection unchecked + return relationalJavaType.unwrap( (R) relationalValue, type, options ); } else { //noinspection unchecked @@ -143,10 +147,12 @@ public X unwrap(J value, Class type, WrapperOptions options) { @Override public J wrap(X value, WrapperOptions options) { - final BasicValueConverter converter = userType.getValueConverter(); + final BasicValueConverter converter = customType.getValueConverter(); if ( value != null && !userType.returnedClass().isInstance( value ) && converter != null ) { - final J domainValue = converter.toDomainValue( value ); - return converter.getDomainJavaType().wrap( domainValue, options ); + final JavaType domainJavaType = converter.getDomainJavaType(); + final Object domainValue = customType.convertToDomainValue( value ); + assert domainJavaType.isInstance( value ); + return domainJavaType.wrap( domainValue, options ); } else { //noinspection unchecked @@ -159,7 +165,7 @@ public Class getJavaTypeClass() { return userType.returnedClass(); } - public static class MutabilityPlanWrapper implements MutabilityPlan { + public class MutabilityPlanWrapper implements MutabilityPlan { private final UserType userType; public MutabilityPlanWrapper(UserType userType) { @@ -183,14 +189,20 @@ public Serializable disassemble(J value, SharedSessionContract session) { // we have to handle the fact that it could produce a null value, // in which case we will try to use a converter for disassembling, // or if that doesn't exist, simply use the domain value as is - if ( disassembled == null && value != null ) { - final BasicValueConverter converter = userType.getValueConverter(); - return converter == null - ? (Serializable) value - : converter.getRelationalJavaType().getMutabilityPlan() - .disassemble( converter.toRelationalValue( value ), session ); + return disassembled == null && value != null + ? disassemble( value, customType.getValueConverter(), session ) + : disassembled; + } + + private Serializable disassemble(J value, BasicValueConverter converter, SharedSessionContract session) { + if ( converter == null ) { + return (Serializable) value; + } + else { + final Object converted = customType.convertToRelationalValue( value ); + return converter.getRelationalJavaType().getMutabilityPlan() + .disassemble( (R) converted, session ); } - return disassembled; } @Override @@ -200,12 +212,21 @@ public J assemble(Serializable cached, SharedSessionContract session) { // we have to handle the fact that it could produce a null value, // in which case we will try to use a converter for assembling, // or if that doesn't exist, simply use the relational value as is - if ( assembled == null && cached != null ) { - final BasicValueConverter converter = userType.getValueConverter(); - return converter == null ? (J) cached : converter.toDomainValue( cached ); + return assembled == null && cached != null + ? disassemble( cached, customType.getValueConverter(), session ) + : assembled; + } + + private J disassemble(Serializable cached, BasicValueConverter converter, SharedSessionContract session) { + if ( converter == null ) { + //noinspection unchecked + return (J) cached; } else { - return assembled; + final Object assembled = + converter.getRelationalJavaType().getMutabilityPlan() + .assemble( cached, session ); + return (J) customType.convertToDomainValue( assembled ); } } } diff --git a/hibernate-core/src/main/java/org/hibernate/type/internal/UserTypeVersionJavaTypeWrapper.java b/hibernate-core/src/main/java/org/hibernate/type/internal/UserTypeVersionJavaTypeWrapper.java index 069ced966eeb..12e9ffb76ea7 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/internal/UserTypeVersionJavaTypeWrapper.java +++ b/hibernate-core/src/main/java/org/hibernate/type/internal/UserTypeVersionJavaTypeWrapper.java @@ -5,6 +5,7 @@ package org.hibernate.type.internal; import org.hibernate.engine.spi.SharedSessionContractImplementor; +import org.hibernate.type.CustomType; import org.hibernate.type.descriptor.java.VersionJavaType; import org.hibernate.usertype.UserVersionType; @@ -14,8 +15,8 @@ */ public class UserTypeVersionJavaTypeWrapper extends UserTypeJavaTypeWrapper implements VersionJavaType { - public UserTypeVersionJavaTypeWrapper(UserVersionType userType) { - super( userType ); + public UserTypeVersionJavaTypeWrapper(UserVersionType userType, CustomType customType) { + super( userType, customType ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/usertype/BaseUserTypeSupport.java b/hibernate-core/src/main/java/org/hibernate/usertype/BaseUserTypeSupport.java index 61a85a3fb49a..4f7c350d058b 100644 --- a/hibernate-core/src/main/java/org/hibernate/usertype/BaseUserTypeSupport.java +++ b/hibernate-core/src/main/java/org/hibernate/usertype/BaseUserTypeSupport.java @@ -33,19 +33,17 @@ public abstract class BaseUserTypeSupport implements UserType { protected abstract void resolve(BiConsumer, JdbcType> resolutionConsumer); private void ensureResolved() { - if ( resolved ) { - return; - } - - resolve( (javaType,jdbcType) -> { - this.javaType = javaType; - this.jdbcType = jdbcType; + if ( !resolved ) { + resolve( (javaType, jdbcType) -> { + this.javaType = javaType; + this.jdbcType = jdbcType; - jdbcValueExtractor = jdbcType.getExtractor( javaType ); - jdbcValueBinder = jdbcType.getBinder( javaType ); + jdbcValueExtractor = jdbcType.getExtractor( javaType ); + jdbcValueBinder = jdbcType.getBinder( javaType ); - resolved = true; - }); + resolved = true; + } ); + } } protected JdbcType jdbcType() { diff --git a/hibernate-core/src/main/java/org/hibernate/usertype/UserType.java b/hibernate-core/src/main/java/org/hibernate/usertype/UserType.java index 74c3c9e79797..96757961a1bf 100644 --- a/hibernate-core/src/main/java/org/hibernate/usertype/UserType.java +++ b/hibernate-core/src/main/java/org/hibernate/usertype/UserType.java @@ -10,15 +10,14 @@ import java.sql.SQLException; import java.util.Objects; +import jakarta.persistence.AttributeConverter; import org.hibernate.Incubating; import org.hibernate.dialect.Dialect; import org.hibernate.engine.jdbc.Size; import org.hibernate.engine.spi.SharedSessionContractImplementor; import org.hibernate.metamodel.mapping.JdbcMapping; import org.hibernate.type.descriptor.WrapperOptions; -import org.hibernate.type.descriptor.converter.spi.BasicValueConverter; import org.hibernate.type.descriptor.jdbc.JdbcType; -import org.hibernate.type.spi.TypeConfiguration; /** * This interface should be implemented by user-defined custom types @@ -310,6 +309,8 @@ default J nullSafeGet(ResultSet rs, int position, SharedSessionContractImplement * {@link ResultSet#getObject(int, Class)} with the * given {@code position} and with the * {@linkplain #returnedClass returned class}. + * + * @since 7.0 */ default J nullSafeGet(ResultSet rs, int position, WrapperOptions options) throws SQLException { @@ -346,6 +347,8 @@ default void nullSafeSet(PreparedStatement st, J value, int position, SharedSess * {@link PreparedStatement#setObject(int, Object, int)} * with the given {@code position} and {@code value} and * with the {@linkplain #getSqlType SQL type}. + * + * @since 7.0 */ default void nullSafeSet(PreparedStatement st, J value, int position, WrapperOptions options) throws SQLException { @@ -480,32 +483,65 @@ default J replace(J detached, J managed, Object owner) { /** * The default column length, for use in DDL generation. + * + * @since 7.0 */ - default long getDefaultSqlLength(Dialect dialect, JdbcType jdbcType) { + default long getDefaultSqlLength() { return Size.DEFAULT_LENGTH; } /** * The default column precision, for use in DDL generation. + * + * @since 7.0 */ - default int getDefaultSqlPrecision(Dialect dialect, JdbcType jdbcType) { + default int getDefaultSqlPrecision() { return Size.DEFAULT_PRECISION; } /** * The default column scale, for use in DDL generation. + * + * @since 7.0 */ - default int getDefaultSqlScale(Dialect dialect, JdbcType jdbcType) { + default int getDefaultSqlScale() { return Size.DEFAULT_SCALE; } /** - * A mapped {@link JdbcType}. By default, the {@code JdbcType} - * registered under our {@linkplain #getSqlType type code}. + * The default column length, for use in DDL generation. + * + * @since 6.0 + * @deprecated This operation is a layer-breaker. + * Use {@link #getDefaultSqlLength()} */ - @Incubating - default JdbcType getJdbcType(TypeConfiguration typeConfiguration) { - return typeConfiguration.getJdbcTypeRegistry().getDescriptor( getSqlType() ); + @Deprecated(since = "7.0", forRemoval = true) + default long getDefaultSqlLength(Dialect dialect, JdbcType jdbcType) { + return getDefaultSqlLength(); + } + + /** + * The default column precision, for use in DDL generation. + * + * @since 6.0 + * @deprecated This operation is a layer-breaker. + * Use {@link #getDefaultSqlPrecision()} + */ + @Deprecated(since = "7.0", forRemoval = true) + default int getDefaultSqlPrecision(Dialect dialect, JdbcType jdbcType) { + return getDefaultSqlPrecision(); + } + + /** + * The default column scale, for use in DDL generation. + * + * @since 6.0 + * @deprecated This operation is a layer-breaker. + * Use {@link #getDefaultSqlScale()} + */ + @Deprecated(since = "7.0", forRemoval = true) + default int getDefaultSqlScale(Dialect dialect, JdbcType jdbcType) { + return getDefaultSqlScale(); } /** @@ -519,9 +555,11 @@ default JdbcType getJdbcType(TypeConfiguration typeConfiguration) { * given by {@link JdbcMapping#getJdbcJavaType()}. Support for multiple * domain type representations works by converting objects of that type * to the domain type. + * + * @since 7.0 */ @Incubating - default BasicValueConverter getValueConverter() { + default AttributeConverter getValueConverter() { return null; } diff --git a/hibernate-core/src/main/java/org/hibernate/usertype/UserTypeLegacyBridge.java b/hibernate-core/src/main/java/org/hibernate/usertype/UserTypeLegacyBridge.java index 8fca4cc8ef0d..3ac0c36bd8bf 100644 --- a/hibernate-core/src/main/java/org/hibernate/usertype/UserTypeLegacyBridge.java +++ b/hibernate-core/src/main/java/org/hibernate/usertype/UserTypeLegacyBridge.java @@ -10,6 +10,8 @@ import org.hibernate.MappingException; import org.hibernate.annotations.Type; import org.hibernate.type.BasicType; +import org.hibernate.type.descriptor.java.BasicJavaType; +import org.hibernate.type.descriptor.jdbc.JdbcType; import org.hibernate.type.spi.TypeConfiguration; import org.hibernate.type.spi.TypeConfigurationAware; @@ -44,27 +46,26 @@ public void setTypeConfiguration(TypeConfiguration typeConfiguration) { @Override public void setParameterValues(Properties parameters) { - if ( hbmStyleTypeName != null ) { - // assume it was ctor-injected - return; - } - - hbmStyleTypeName = parameters.getProperty( TYPE_NAME_PARAM_KEY ); if ( hbmStyleTypeName == null ) { - throw new MappingException( "Missing `@Parameter` for `" + TYPE_NAME_PARAM_KEY + "`" ); + hbmStyleTypeName = parameters.getProperty( TYPE_NAME_PARAM_KEY ); + if ( hbmStyleTypeName == null ) { + throw new MappingException( "Missing `@Parameter` for `" + TYPE_NAME_PARAM_KEY + "`" ); + } } + // otherwise assume it was ctor-injected } @Override - protected void resolve(BiConsumer resolutionConsumer) { + protected void resolve(BiConsumer, JdbcType> resolutionConsumer) { assert typeConfiguration != null; - final BasicType registeredType = typeConfiguration - .getBasicTypeRegistry() - .getRegisteredType( hbmStyleTypeName ); + final BasicType registeredType = + typeConfiguration.getBasicTypeRegistry() + .getRegisteredType( hbmStyleTypeName ); resolutionConsumer.accept( - registeredType.getJavaTypeDescriptor(), + (BasicJavaType) + registeredType.getJavaTypeDescriptor(), registeredType.getJdbcType() ); } diff --git a/hibernate-core/src/main/java/org/hibernate/usertype/UserTypeSupport.java b/hibernate-core/src/main/java/org/hibernate/usertype/UserTypeSupport.java index a5d4e16c00e5..6a23f1792bf1 100644 --- a/hibernate-core/src/main/java/org/hibernate/usertype/UserTypeSupport.java +++ b/hibernate-core/src/main/java/org/hibernate/usertype/UserTypeSupport.java @@ -7,6 +7,7 @@ import java.util.function.BiConsumer; import org.hibernate.type.descriptor.java.BasicJavaType; +import org.hibernate.type.descriptor.java.JavaType; import org.hibernate.type.descriptor.jdbc.JdbcType; import org.hibernate.type.spi.TypeConfiguration; import org.hibernate.type.spi.TypeConfigurationAware; @@ -15,12 +16,12 @@ * @author Steve Ebersole */ public class UserTypeSupport extends BaseUserTypeSupport implements TypeConfigurationAware { - private final Class returnedClass; + private final Class returnedClass; private final int jdbcTypeCode; private TypeConfiguration typeConfiguration; - public UserTypeSupport(Class returnedClass, int jdbcTypeCode) { + public UserTypeSupport(Class returnedClass, int jdbcTypeCode) { this.returnedClass = returnedClass; this.jdbcTypeCode = jdbcTypeCode; } @@ -28,11 +29,11 @@ public UserTypeSupport(Class returnedClass, int jdbcTypeCode) { @Override protected void resolve(BiConsumer, JdbcType> resolutionConsumer) { assert typeConfiguration != null; - + final JavaType descriptor = + typeConfiguration.getJavaTypeRegistry() + .getDescriptor( returnedClass ); resolutionConsumer.accept( - (BasicJavaType) typeConfiguration - .getJavaTypeRegistry() - .getDescriptor( returnedClass ), + (BasicJavaType) descriptor, typeConfiguration .getJdbcTypeRegistry() .getDescriptor( jdbcTypeCode ) diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/EnumType.java b/hibernate-core/src/test/java/org/hibernate/orm/test/EnumType.java index fcb9b4e0bb54..07b4254bde1a 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/EnumType.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/EnumType.java @@ -67,11 +67,6 @@ public Class getEnumClass() { return enumClass; } - @Override - public JdbcType getJdbcType(TypeConfiguration typeConfiguration) { - return jdbcType; - } - /** *

* An instance of this class is "configured" by a call to {@link #setParameterValues}, diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/type/contributor/ArrayType.java b/hibernate-core/src/test/java/org/hibernate/orm/test/type/contributor/ArrayType.java index f7c932dc43f8..b18cc4584f6b 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/type/contributor/ArrayType.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/type/contributor/ArrayType.java @@ -9,21 +9,18 @@ import java.sql.ResultSet; import java.sql.SQLException; +import jakarta.persistence.AttributeConverter; import org.hibernate.HibernateException; import org.hibernate.type.descriptor.WrapperOptions; -import org.hibernate.type.descriptor.converter.spi.BasicValueConverter; import org.hibernate.type.descriptor.java.BasicJavaType; -import org.hibernate.type.descriptor.java.JavaType; -import org.hibernate.type.descriptor.java.StringJavaType; import org.hibernate.type.descriptor.jdbc.JdbcType; import org.hibernate.type.descriptor.jdbc.VarcharJdbcType; -import org.hibernate.type.spi.TypeConfiguration; import org.hibernate.usertype.UserType; /** * @author Vlad Mihalcea */ -public class ArrayType implements UserType, BasicValueConverter { +public class ArrayType implements UserType, AttributeConverter { public static final ArrayType INSTANCE = new ArrayType(); @@ -35,11 +32,6 @@ public int getSqlType() { return jdbcType.getJdbcTypeCode(); } - @Override - public JdbcType getJdbcType(TypeConfiguration typeConfiguration) { - return jdbcType; - } - @Override public Class returnedClass() { return Array.class; @@ -68,28 +60,18 @@ public void nullSafeSet(PreparedStatement st, Array value, int index, WrapperOpt } @Override - public BasicValueConverter getValueConverter() { - return (BasicValueConverter) this; + public AttributeConverter getValueConverter() { + return this; } @Override - public Array toDomainValue(String relationalForm) { - return assemble( relationalForm, null ); - } - - @Override - public String toRelationalValue(Array domainForm) { + public String convertToDatabaseColumn(Array domainForm) { return (String) disassemble( domainForm ); } @Override - public JavaType getDomainJavaType() { - return javaType; - } - - @Override - public JavaType getRelationalJavaType() { - return StringJavaType.INSTANCE; + public Array convertToEntityAttribute(String relationalForm) { + return assemble( relationalForm, null ); } @Override diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/customtype/EnumType.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/customtype/EnumType.java index 48450a8b1012..117c0ee80b9b 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/customtype/EnumType.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/customtype/EnumType.java @@ -67,11 +67,6 @@ public Class getEnumClass() { return enumClass; } - @Override - public JdbcType getJdbcType(TypeConfiguration typeConfiguration) { - return jdbcType; - } - /** *

* An instance of this class is "configured" by a call to {@link #setParameterValues},