From 95aa8246ed57e37e3c13e4c5c15fb181e02f3b6e Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Thu, 7 Oct 2021 12:17:42 -0500 Subject: [PATCH] HHH-14856 - Introduce @CustomType; HHH-14865 - Re-work @Any and @ManyToAny support; HHH-14863 - Compositional definition of basic value mappings; HHH-14864 - Drop legacy Type-based annotations layer in missed support for `@MapKeyClass` and `@ElementCollection#targetClass` in BasicValue resolution as part of BasicValueBinder handling --- .../org/hibernate/annotations/JavaType.java | 1 + .../hibernate/annotations/MapKeyJavaType.java | 4 ++ .../cfg/annotations/BasicValueBinder.java | 43 ++++++++++++++----- 3 files changed, 37 insertions(+), 11 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/JavaType.java b/hibernate-core/src/main/java/org/hibernate/annotations/JavaType.java index a5ed7b8749..fb39b84b7d 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/JavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/JavaType.java @@ -44,6 +44,7 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; * @see MapKeyJavaType * @see CollectionIdJavaType * @see ListIndexJavaType + * @see AnyKeyJavaType * * @since 6.0 */ diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/MapKeyJavaType.java b/hibernate-core/src/main/java/org/hibernate/annotations/MapKeyJavaType.java index 7a6cc019b1..d4643cd44b 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/MapKeyJavaType.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/MapKeyJavaType.java @@ -11,6 +11,8 @@ import java.lang.annotation.Retention; import org.hibernate.type.descriptor.java.BasicJavaTypeDescriptor; +import jakarta.persistence.MapKeyClass; + import static java.lang.annotation.ElementType.ANNOTATION_TYPE; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.METHOD; @@ -19,6 +21,8 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * Form of {@link JavaType} for describing the key of a Map * + * @see MapKeyClass + * * @since 6.0 */ @java.lang.annotation.Target({METHOD, FIELD, ANNOTATION_TYPE}) diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/BasicValueBinder.java b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/BasicValueBinder.java index 4a239e7efd..e6dff9b503 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/BasicValueBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/BasicValueBinder.java @@ -8,7 +8,6 @@ package org.hibernate.cfg.annotations; import java.io.Serializable; import java.lang.reflect.ParameterizedType; -import java.sql.Types; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; @@ -84,11 +83,12 @@ import org.hibernate.usertype.UserType; import org.jboss.logging.Logger; -import jakarta.persistence.DiscriminatorType; +import jakarta.persistence.ElementCollection; import jakarta.persistence.EnumType; import jakarta.persistence.Enumerated; import jakarta.persistence.Id; import jakarta.persistence.Lob; +import jakarta.persistence.MapKeyClass; import jakarta.persistence.MapKeyEnumerated; import jakarta.persistence.MapKeyTemporal; import jakarta.persistence.Temporal; @@ -139,7 +139,7 @@ public class BasicValueBinder implements JdbcTypeDescriptorIndicators { private Map explicitLocalTypeParams; private Function explicitJdbcTypeAccess; - private Function explicitJtdAccess; + private Function explicitJavaTypeAccess; private Function explicitMutabilityAccess; private Function implicitJavaTypeAccess; @@ -390,7 +390,7 @@ public class BasicValueBinder implements JdbcTypeDescriptorIndicators { explicitBasicTypeName = null; implicitJavaTypeAccess = (typeConfiguration) -> null; - explicitJtdAccess = (typeConfiguration) -> { + explicitJavaTypeAccess = (typeConfiguration) -> { final CollectionIdJavaType javaTypeAnn = modelXProperty.getAnnotation( CollectionIdJavaType.class ); if ( javaTypeAnn != null ) { final Class> javaType = normalizeJavaType( javaTypeAnn.value() ); @@ -515,7 +515,7 @@ public class BasicValueBinder implements JdbcTypeDescriptorIndicators { return null; }; - explicitJtdAccess = typeConfiguration -> { + explicitJavaTypeAccess = typeConfiguration -> { final MapKeyJavaType javaTypeAnn = mapAttribute.getAnnotation( MapKeyJavaType.class ); if ( javaTypeAnn != null ) { final Class> jdbcTypeImpl = normalizeJavaType( javaTypeAnn.value() ); @@ -525,6 +525,11 @@ public class BasicValueBinder implements JdbcTypeDescriptorIndicators { } } + final MapKeyClass mapKeyClassAnn = mapAttribute.getAnnotation( MapKeyClass.class ); + if ( mapKeyClassAnn != null ) { + return (BasicJavaTypeDescriptor) typeConfiguration.getJavaTypeDescriptorRegistry().getDescriptor( mapKeyClassAnn.value() ); + } + return null; }; @@ -575,7 +580,7 @@ public class BasicValueBinder implements JdbcTypeDescriptorIndicators { .getServiceRegistry() .getService( ManagedBeanRegistry.class ); - explicitJtdAccess = (typeConfiguration) -> { + explicitJavaTypeAccess = (typeConfiguration) -> { final ListIndexJavaType javaTypeAnn = listAttribute.getAnnotation( ListIndexJavaType.class ); if ( javaTypeAnn != null ) { final Class> javaType = normalizeJavaType( javaTypeAnn.value() ); @@ -609,8 +614,6 @@ public class BasicValueBinder implements JdbcTypeDescriptorIndicators { private void prepareCollectionElement(XProperty attributeXProperty, XClass elementTypeXClass) { - // todo (6.0) : @SqlType / @SqlTypeDescriptor - Class javaType; //noinspection unchecked if ( elementTypeXClass == null && attributeXProperty.isArray() ) { @@ -659,6 +662,24 @@ public class BasicValueBinder implements JdbcTypeDescriptorIndicators { } normalSupplementalDetails( attributeXProperty, buildingContext ); + + // layer in support for JPA's approach for specifying a specific Java type for the collection elements... + final ElementCollection elementCollectionAnn = attributeXProperty.getAnnotation( ElementCollection.class ); + if ( elementCollectionAnn != null + && elementCollectionAnn.targetClass() != null + && elementCollectionAnn.targetClass() != void.class ) { + final Function original = explicitJavaTypeAccess; + explicitJavaTypeAccess = (typeConfiguration) -> { + final BasicJavaTypeDescriptor originalResult = original.apply( typeConfiguration ); + if ( originalResult != null ) { + return originalResult; + } + + return (BasicJavaTypeDescriptor) typeConfiguration + .getJavaTypeDescriptorRegistry() + .getDescriptor( elementCollectionAnn.targetClass() ); + }; + } } @SuppressWarnings("unchecked") @@ -761,7 +782,7 @@ public class BasicValueBinder implements JdbcTypeDescriptorIndicators { .getServiceRegistry() .getService( ManagedBeanRegistry.class ); - explicitJtdAccess = (typeConfiguration) -> { + explicitJavaTypeAccess = (typeConfiguration) -> { final AnyKeyJavaType javaTypeAnn = modelXProperty.getAnnotation( AnyKeyJavaType.class ); if ( javaTypeAnn != null ) { final Class> javaType = normalizeJavaType( javaTypeAnn.value() ); @@ -891,7 +912,7 @@ public class BasicValueBinder implements JdbcTypeDescriptorIndicators { .getServiceRegistry() .getService( ManagedBeanRegistry.class ); - explicitJtdAccess = typeConfiguration -> { + explicitJavaTypeAccess = typeConfiguration -> { final JavaType javaTypeAnn = attributeXProperty.getAnnotation( JavaType.class ); if ( javaTypeAnn != null ) { final Class> javaType = normalizeJavaType( javaTypeAnn.value() ); @@ -1162,7 +1183,7 @@ public class BasicValueBinder implements JdbcTypeDescriptorIndicators { basicValue.setJpaAttributeConverterDescriptor( converterDescriptor ); basicValue.setImplicitJavaTypeAccess( implicitJavaTypeAccess ); - basicValue.setExplicitJavaTypeAccess( explicitJtdAccess ); + basicValue.setExplicitJavaTypeAccess( explicitJavaTypeAccess ); basicValue.setExplicitJdbcTypeAccess( explicitJdbcTypeAccess ); basicValue.setExplicitMutabilityPlanAccess( explicitMutabilityAccess );