From 7b3bda3e41b21e188d8235734f435e0f1cc2ebce Mon Sep 17 00:00:00 2001 From: Gavin King Date: Wed, 8 Oct 2025 11:47:46 +0200 Subject: [PATCH] minor cleanups to AnnotationBinder 1. code formatting 2. don't leak an annotation type onto InFlightMetadataCollector SPI 3. use a record --- .../InFlightMetadataCollectorImpl.java | 32 +---- .../boot/model/internal/AnnotationBinder.java | 115 ++++++++++++------ .../boot/model/internal/CollectionBinder.java | 4 +- .../boot/spi/InFlightMetadataCollector.java | 23 +--- 4 files changed, 89 insertions(+), 85 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java index ca339794514a..186fbb1da563 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java @@ -15,7 +15,6 @@ import org.hibernate.MappingException; import org.hibernate.annotations.CollectionTypeRegistration; import org.hibernate.annotations.Imported; -import org.hibernate.annotations.Parameter; import org.hibernate.boot.CacheRegionDefinition; import org.hibernate.boot.SessionFactoryBuilder; import org.hibernate.boot.model.IdentifierGeneratorDefinition; @@ -113,13 +112,12 @@ import java.util.function.Supplier; import static java.util.Collections.emptyList; +import static org.hibernate.boot.model.internal.AnnotationBinder.extractParameters; import static org.hibernate.boot.model.naming.Identifier.toIdentifier; import static org.hibernate.boot.model.relational.internal.SqlStringGenerationContextImpl.fromExplicit; import static org.hibernate.cfg.MappingSettings.DEFAULT_CATALOG; import static org.hibernate.cfg.MappingSettings.DEFAULT_SCHEMA; import static org.hibernate.boot.BootLogging.BOOT_LOGGER; -import static org.hibernate.internal.util.collections.CollectionHelper.isEmpty; -import static org.hibernate.internal.util.collections.CollectionHelper.mapOfSize; /** * The implementation of the {@linkplain InFlightMetadataCollector in-flight @@ -509,10 +507,11 @@ public Class> findRegisteredUserType(Class basicType) { private Map collectionTypeRegistrations; - @Override - public void addCollectionTypeRegistration(CollectionTypeRegistration registrationAnnotation) { - addCollectionTypeRegistration( registrationAnnotation.classification(), - toDescriptor( registrationAnnotation ) ); + @Override @Deprecated(forRemoval = true) + public void addCollectionTypeRegistration(CollectionTypeRegistration registration) { + addCollectionTypeRegistration( registration.classification(), + new CollectionTypeRegistrationDescriptor( registration.type(), + extractParameters( registration.parameters() ) ) ); } @Override @@ -530,25 +529,6 @@ public CollectionTypeRegistrationDescriptor findCollectionTypeRegistration(Colle } - private CollectionTypeRegistrationDescriptor toDescriptor(CollectionTypeRegistration registrationAnnotation) { - return new CollectionTypeRegistrationDescriptor( registrationAnnotation.type(), - extractParameters( registrationAnnotation.parameters() ) ); - } - - private Map extractParameters(Parameter[] annotationUsages) { - if ( isEmpty( annotationUsages ) ) { - return null; - } - else { - final Map result = mapOfSize( annotationUsages.length ); - for ( Parameter parameter : annotationUsages ) { - result.put( parameter.name(), parameter.value() ); - } - return result; - } - } - - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // attribute converters diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/AnnotationBinder.java b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/AnnotationBinder.java index aad4f0e884ce..bb89b313fea6 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/AnnotationBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/AnnotationBinder.java @@ -7,7 +7,6 @@ import jakarta.persistence.Entity; import jakarta.persistence.FetchType; import jakarta.persistence.Inheritance; -import jakarta.persistence.InheritanceType; import jakarta.persistence.MappedSuperclass; import jakarta.persistence.Table; import org.hibernate.AnnotationException; @@ -21,6 +20,7 @@ import org.hibernate.annotations.Imported; import org.hibernate.annotations.JavaTypeRegistration; import org.hibernate.annotations.JdbcTypeRegistration; +import org.hibernate.annotations.Parameter; import org.hibernate.annotations.TypeRegistration; import org.hibernate.boot.model.IdentifierGeneratorDefinition; import org.hibernate.boot.model.NamedEntityGraphDefinition; @@ -28,6 +28,7 @@ import org.hibernate.boot.models.HibernateAnnotations; import org.hibernate.boot.models.JpaAnnotations; import org.hibernate.boot.registry.classloading.spi.ClassLoaderService; +import org.hibernate.boot.spi.InFlightMetadataCollector.CollectionTypeRegistrationDescriptor; import org.hibernate.boot.spi.MetadataBuildingContext; import org.hibernate.models.spi.AnnotationTarget; import org.hibernate.models.spi.ClassDetails; @@ -40,6 +41,7 @@ import java.util.List; import java.util.Map; +import static jakarta.persistence.InheritanceType.SINGLE_TABLE; import static org.hibernate.boot.model.internal.AnnotatedClassType.EMBEDDABLE; import static org.hibernate.boot.model.internal.AnnotatedClassType.ENTITY; import static org.hibernate.boot.model.internal.EntityBinder.bindEntityClass; @@ -55,6 +57,8 @@ import static org.hibernate.boot.model.internal.QueryBinder.bindQuery; import static org.hibernate.boot.model.internal.QueryBinder.bindSqlResultSetMapping; import static org.hibernate.internal.util.StringHelper.unqualify; +import static org.hibernate.internal.util.collections.CollectionHelper.isEmpty; +import static org.hibernate.internal.util.collections.CollectionHelper.mapOfSize; import static org.hibernate.mapping.MetadataSource.ANNOTATIONS; /** @@ -74,27 +78,25 @@ public static void bindDefaults(MetadataBuildingContext context) { final var metadataCollector = context.getMetadataCollector(); final var globalRegistrations = metadataCollector.getGlobalRegistrations(); - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // id generators globalRegistrations.getSequenceGeneratorRegistrations().forEach( (name, generatorRegistration) -> { final var definitionBuilder = new IdentifierGeneratorDefinition.Builder(); interpretSequenceGenerator( generatorRegistration.configuration(), definitionBuilder ); - final var idGenDef = definitionBuilder.build(); + final var generatorDefinition = definitionBuilder.build(); BOOT_LOGGER.addingGlobalSequenceGenerator( name ); - metadataCollector.addDefaultIdentifierGenerator( idGenDef ); + metadataCollector.addDefaultIdentifierGenerator( generatorDefinition ); } ); globalRegistrations.getTableGeneratorRegistrations().forEach( (name, generatorRegistration) -> { final var definitionBuilder = new IdentifierGeneratorDefinition.Builder(); interpretTableGenerator( generatorRegistration.configuration(), definitionBuilder ); - final var idGenDef = definitionBuilder.build(); + final var generatorDefinition = definitionBuilder.build(); BOOT_LOGGER.addingGlobalTableGenerator( name ); - metadataCollector.addDefaultIdentifierGenerator( idGenDef ); + metadataCollector.addDefaultIdentifierGenerator( generatorDefinition ); } ); - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // result-set-mappings @@ -102,7 +104,6 @@ public static void bindDefaults(MetadataBuildingContext context) { bindSqlResultSetMapping( mappingRegistration.configuration(), context, true ); } ); - // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // queries @@ -177,13 +178,13 @@ private static void bindNamedHibernateQueries(AnnotationTarget annotationTarget, annotationTarget.forEachRepeatedAnnotationUsages( HibernateAnnotations.NAMED_QUERY, sourceModelContext, - (usage) -> bindQuery( usage, context, annotationTarget ) + usage -> bindQuery( usage, context, annotationTarget ) ); annotationTarget.forEachRepeatedAnnotationUsages( HibernateAnnotations.NAMED_NATIVE_QUERY, sourceModelContext, - (usage) -> bindNativeQuery( usage, context, annotationTarget ) + usage -> bindNativeQuery( usage, context, annotationTarget ) ); } @@ -193,25 +194,25 @@ private static void bindNamedJpaQueries(AnnotationTarget annotationTarget, Metad annotationTarget.forEachRepeatedAnnotationUsages( JpaAnnotations.SQL_RESULT_SET_MAPPING, sourceModelContext, - (usage) -> bindSqlResultSetMapping( usage, context,false ) + usage -> bindSqlResultSetMapping( usage, context,false ) ); annotationTarget.forEachRepeatedAnnotationUsages( JpaAnnotations.NAMED_QUERY, sourceModelContext, - (usage) -> bindQuery( usage, context, false, annotationTarget ) + usage -> bindQuery( usage, context, false, annotationTarget ) ); annotationTarget.forEachRepeatedAnnotationUsages( JpaAnnotations.NAMED_NATIVE_QUERY, sourceModelContext, - (usage) -> bindNativeQuery( usage, context, annotationTarget, false ) + usage -> bindNativeQuery( usage, context, annotationTarget, false ) ); annotationTarget.forEachRepeatedAnnotationUsages( JpaAnnotations.NAMED_STORED_PROCEDURE_QUERY, sourceModelContext, - (usage) -> bindNamedStoredProcedureQuery( usage, context, false ) + usage -> bindNamedStoredProcedureQuery( usage, context, false ) ); } @@ -226,7 +227,8 @@ private static void bindNamedJpaQueries(AnnotationTarget annotationTarget, Metad public static void bindClass( ClassDetails classDetails, Map inheritanceStatePerClass, - MetadataBuildingContext context) throws MappingException { + MetadataBuildingContext context) + throws MappingException { detectMappedSuperclassProblems( classDetails ); @@ -257,7 +259,7 @@ private static void handleImport(ClassDetails annotatedClass, MetadataBuildingCo private static void detectMappedSuperclassProblems(ClassDetails annotatedClass) { if ( annotatedClass.hasDirectAnnotationUsage( MappedSuperclass.class ) ) { - //@Entity and @MappedSuperclass on the same class leads to a NPE down the road + // @Entity and @MappedSuperclass on the same class leads to NPE down the road if ( annotatedClass.hasDirectAnnotationUsage( Entity.class ) ) { throw new AnnotationException( "Type '" + annotatedClass.getName() + "' is annotated both '@Entity' and '@MappedSuperclass'" ); @@ -279,17 +281,45 @@ private static void bindTypeDescriptorRegistrations( final var managedBeanRegistry = context.getBootstrapContext().getManagedBeanRegistry(); final var sourceModelContext = modelsContext( context ); - annotatedElement.forEachAnnotationUsage( JavaTypeRegistration.class, sourceModelContext, (usage) -> { - handleJavaTypeRegistration( context, managedBeanRegistry, usage ); - } ); + annotatedElement.forEachAnnotationUsage( + JavaTypeRegistration.class, + sourceModelContext, + usage -> handleJavaTypeRegistration( context, managedBeanRegistry, usage ) + ); - annotatedElement.forEachAnnotationUsage( JdbcTypeRegistration.class, sourceModelContext, (usage) -> { - handleJdbcTypeRegistration( context, managedBeanRegistry, usage ); - } ); + annotatedElement.forEachAnnotationUsage( + JdbcTypeRegistration.class, + sourceModelContext, + usage -> handleJdbcTypeRegistration( context, managedBeanRegistry, usage ) + ); - annotatedElement.forEachAnnotationUsage( CollectionTypeRegistration.class, sourceModelContext, (usage) -> { - context.getMetadataCollector().addCollectionTypeRegistration( usage ); - } ); + annotatedElement.forEachAnnotationUsage( + CollectionTypeRegistration.class, + sourceModelContext, + usage -> handleCollectionTypeRegistration( context, usage ) + ); + } + + private static void handleCollectionTypeRegistration( + MetadataBuildingContext context, + CollectionTypeRegistration annotation) { + context.getMetadataCollector() + .addCollectionTypeRegistration( annotation.classification(), + new CollectionTypeRegistrationDescriptor( annotation.type(), + extractParameters( annotation.parameters() ) ) ); + } + + public static Map extractParameters(Parameter[] parameters) { + if ( isEmpty( parameters ) ) { + return null; + } + else { + final Map result = mapOfSize( parameters.length ); + for ( var parameter : parameters ) { + result.put( parameter.name(), parameter.value() ); + } + return result; + } } private static void handleJdbcTypeRegistration( @@ -329,9 +359,11 @@ private static T getBean( private static void bindEmbeddableInstantiatorRegistrations( AnnotationTarget annotatedElement, MetadataBuildingContext context) { - annotatedElement.forEachAnnotationUsage( EmbeddableInstantiatorRegistration.class, modelsContext( context ), (usage) -> { - handleEmbeddableInstantiatorRegistration( context, usage ); - } ); + annotatedElement.forEachAnnotationUsage( + EmbeddableInstantiatorRegistration.class, + modelsContext( context ), + usage -> handleEmbeddableInstantiatorRegistration( context, usage ) + ); } private static void handleEmbeddableInstantiatorRegistration( @@ -346,17 +378,21 @@ private static void handleEmbeddableInstantiatorRegistration( private static void bindCompositeUserTypeRegistrations( AnnotationTarget annotatedElement, MetadataBuildingContext context) { - annotatedElement.forEachAnnotationUsage( CompositeTypeRegistration.class, modelsContext( context ), (usage) -> { - handleCompositeUserTypeRegistration( context, usage ); - } ); + annotatedElement.forEachAnnotationUsage( + CompositeTypeRegistration.class, + modelsContext( context ), + usage -> handleCompositeUserTypeRegistration( context, usage ) + ); } private static void bindUserTypeRegistrations( AnnotationTarget annotatedElement, MetadataBuildingContext context) { - annotatedElement.forEachAnnotationUsage( TypeRegistration.class, modelsContext( context ), (usage) -> { - handleUserTypeRegistration( context, usage ); - } ); + annotatedElement.forEachAnnotationUsage( + TypeRegistration.class, + modelsContext( context ), + usage -> handleUserTypeRegistration( context, usage ) + ); } private static void handleUserTypeRegistration( @@ -382,10 +418,11 @@ private static void handleCompositeUserTypeRegistration( } private static void bindConverterRegistrations(AnnotationTarget container, MetadataBuildingContext context) { - final ModelsContext sourceModelContext = modelsContext( context ); - container.forEachAnnotationUsage( ConverterRegistration.class, sourceModelContext, (usage) -> { - handleConverterRegistration( usage, context ); - } ); + container.forEachAnnotationUsage( + ConverterRegistration.class, + modelsContext( context ), + usage -> handleConverterRegistration( usage, context ) + ); } private static void handleConverterRegistration(ConverterRegistration registration, MetadataBuildingContext context) { @@ -500,7 +537,7 @@ private static void checkMixedInheritance(ClassDetails classDetails, Inheritance final var inheritanceType = state.getType(); final var superclassInheritanceType = superclassState.getType(); if ( inheritanceType != null && superclassInheritanceType != null ) { - final boolean nonDefault = InheritanceType.SINGLE_TABLE != inheritanceType; + final boolean nonDefault = SINGLE_TABLE != inheritanceType; final boolean mixingStrategy = inheritanceType != superclassInheritanceType; if ( nonDefault && mixingStrategy ) { throw new AnnotationException( "Entity '" + classDetails.getName() diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/CollectionBinder.java b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/CollectionBinder.java index 00f1c3977530..f60ab5e44969 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/CollectionBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/CollectionBinder.java @@ -798,8 +798,8 @@ private static CollectionBinder createBinderFromTypeRegistration( property, () -> createUserTypeBean( property.getDeclaringType().getName() + "#" + property.getName(), - typeRegistration.getImplementation(), - typeRegistration.getParameters(), + typeRegistration.implementation(), + typeRegistration.parameters(), context.getBootstrapContext(), context.getMetadataCollector().getMetadataBuildingOptions().isAllowExtensionsInCdi() ), diff --git a/hibernate-core/src/main/java/org/hibernate/boot/spi/InFlightMetadataCollector.java b/hibernate-core/src/main/java/org/hibernate/boot/spi/InFlightMetadataCollector.java index 76230298c461..fc2903a9660e 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/spi/InFlightMetadataCollector.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/spi/InFlightMetadataCollector.java @@ -13,7 +13,6 @@ import org.hibernate.DuplicateMappingException; import org.hibernate.HibernateException; import org.hibernate.MappingException; -import org.hibernate.annotations.CollectionTypeRegistration; import org.hibernate.boot.internal.NamedProcedureCallDefinitionImpl; import org.hibernate.boot.model.IdentifierGeneratorDefinition; import org.hibernate.boot.model.NamedEntityGraphDefinition; @@ -359,7 +358,8 @@ void addTableNameBinding( void registerUserType(Class embeddableType, Class> userType); Class> findRegisteredUserType(Class basicType); - void addCollectionTypeRegistration(CollectionTypeRegistration registrationAnnotation); + @Deprecated(since = "7.2", forRemoval = true) // let's not leak annotation types onto this SPI + void addCollectionTypeRegistration(org.hibernate.annotations.CollectionTypeRegistration registrationAnnotation); void addCollectionTypeRegistration(CollectionClassification classification, CollectionTypeRegistrationDescriptor descriptor); CollectionTypeRegistrationDescriptor findCollectionTypeRegistration(CollectionClassification classification); @@ -408,21 +408,8 @@ EntityTableXref addEntityTableXref( Map getJoins(String entityName); - class CollectionTypeRegistrationDescriptor { - private final Class implementation; - private final Map parameters; - - public CollectionTypeRegistrationDescriptor(Class implementation, Map parameters) { - this.implementation = implementation; - this.parameters = parameters; - } - - public Class getImplementation() { - return implementation; - } - - public Map getParameters() { - return parameters; - } + record CollectionTypeRegistrationDescriptor( + Class implementation, + Map parameters) { } }