From 169b9a849c025878fe28625088632e6d3c01b538 Mon Sep 17 00:00:00 2001 From: Gavin Date: Sun, 25 Dec 2022 23:04:51 +0100 Subject: [PATCH] drop arbitrary restrictions on what annotations can go where also add an error for competing @FilterDefs --- .../boot/model/internal/AnnotationBinder.java | 56 +++++++++---------- .../boot/model/internal/CollectionBinder.java | 10 ++-- .../boot/model/internal/EntityBinder.java | 11 ++-- .../boot/model/internal/MapBinder.java | 3 +- ...AnnotationMetadataSourceProcessorImpl.java | 11 +--- .../annotations/manytomany/GroupWithSet.java | 1 - 6 files changed, 42 insertions(+), 50 deletions(-) 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 7dac644e30..877ee4145e 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 @@ -147,6 +147,7 @@ import org.hibernate.usertype.UserType; import org.hibernate.usertype.internal.OffsetDateTimeCompositeUserType; import org.hibernate.usertype.internal.ZonedDateTimeCompositeUserType; +import static org.hibernate.boot.model.internal.AnnotatedClassType.ENTITY; import static org.hibernate.boot.model.internal.BinderHelper.getMappedSuperclassOrNull; import static org.hibernate.boot.model.internal.BinderHelper.getOverridableAnnotation; import static org.hibernate.boot.model.internal.BinderHelper.getPath; @@ -305,11 +306,11 @@ public final class AnnotationBinder { handleIdGenerators( annotatedPackage, context ); - handleTypeDescriptorRegistrations( annotatedPackage, context ); + bindTypeDescriptorRegistrations( annotatedPackage, context ); bindEmbeddableInstantiatorRegistrations( annotatedPackage, context ); bindUserTypeRegistrations( annotatedPackage, context ); bindCompositeUserTypeRegistrations( annotatedPackage, context ); - handleConverterRegistrations( annotatedPackage, context ); + bindConverterRegistrations( annotatedPackage, context ); bindGenericGenerators( annotatedPackage, context ); bindQueries( annotatedPackage, context ); @@ -520,31 +521,20 @@ public final class AnnotationBinder { detectMappedSuperclassProblems( annotatedClass ); - switch ( context.getMetadataCollector().getClassType( annotatedClass ) ) { - case MAPPED_SUPERCLASS: - // Allow queries and filters to be declared by a @MappedSuperclass - bindQueries( annotatedClass, context ); - bindFilterDefs( annotatedClass, context ); - //fall through: - case IMPORTED: - handleImport( annotatedClass, context ); - case EMBEDDABLE: - case NONE: - return; - } - - // try to find class level generators - final Map generators = buildGenerators( annotatedClass, context ); - handleTypeDescriptorRegistrations( annotatedClass, context ); + bindQueries( annotatedClass, context ); + handleImport( annotatedClass, context ); + bindFilterDefs( annotatedClass, context ); + bindTypeDescriptorRegistrations( annotatedClass, context ); bindEmbeddableInstantiatorRegistrations( annotatedClass, context ); bindUserTypeRegistrations( annotatedClass, context ); bindCompositeUserTypeRegistrations( annotatedClass, context ); - handleConverterRegistrations( annotatedClass, context ); + bindConverterRegistrations( annotatedClass, context ); - bindQueries( annotatedClass, context ); - bindFilterDefs( annotatedClass, context ); - - EntityBinder.bindEntityClass( annotatedClass, inheritanceStatePerClass, generators, context ); + // try to find class level generators + final Map generators = buildGenerators( annotatedClass, context ); + if ( context.getMetadataCollector().getClassType( annotatedClass ) == ENTITY ) { + EntityBinder.bindEntityClass( annotatedClass, inheritanceStatePerClass, generators, context ); + } } private static void handleImport(XClass annotatedClass, MetadataBuildingContext context) { @@ -570,7 +560,7 @@ public final class AnnotationBinder { } } - private static void handleTypeDescriptorRegistrations(XAnnotatedElement annotatedElement, MetadataBuildingContext context) { + private static void bindTypeDescriptorRegistrations(XAnnotatedElement annotatedElement, MetadataBuildingContext context) { final ManagedBeanRegistry managedBeanRegistry = context.getBootstrapContext() .getServiceRegistry() .getService( ManagedBeanRegistry.class ); @@ -726,7 +716,7 @@ public final class AnnotationBinder { ); } - private static void handleConverterRegistrations(XAnnotatedElement container, MetadataBuildingContext context) { + private static void bindConverterRegistrations(XAnnotatedElement container, MetadataBuildingContext context) { final ConverterRegistration converterRegistration = container.getAnnotation( ConverterRegistration.class ); if ( converterRegistration != null ) { handleConverterRegistration( converterRegistration, context ); @@ -769,6 +759,10 @@ public final class AnnotationBinder { private static void bindFilterDef(FilterDef filterDef, MetadataBuildingContext context) { final Map explicitParamJaMappings = filterDef.parameters().length == 0 ? null : new HashMap<>(); + final String name = filterDef.name(); + if ( context.getMetadataCollector().getFilterDefinition( name ) != null ) { + throw new AnnotationException( "Multiple '@FilterDef' annotations define a filter named '" + name + "'" ); + } for ( ParamDef paramDef : filterDef.parameters() ) { final JdbcMapping jdbcMapping = resolveFilterParamType( paramDef.type(), context ); if ( jdbcMapping == null ) { @@ -777,14 +771,14 @@ public final class AnnotationBinder { Locale.ROOT, "Unable to resolve type specified for parameter (%s) defined for @FilterDef (%s)", paramDef.name(), - filterDef.name() + name ) ); } explicitParamJaMappings.put( paramDef.name(), jdbcMapping ); } final FilterDefinition filterDefinition = - new FilterDefinition( filterDef.name(), filterDef.defaultCondition(), explicitParamJaMappings ); + new FilterDefinition(name, filterDef.defaultCondition(), explicitParamJaMappings ); LOG.debugf( "Binding filter definition: %s", filterDefinition.getFilterName() ); context.getMetadataCollector().addFilterDefinition( filterDefinition ); } @@ -2484,7 +2478,6 @@ public final class AnnotationBinder { final InheritanceState state = new InheritanceState( clazz, inheritanceStatePerClass, buildingContext ); if ( superclassState != null ) { //the classes are ordered thus preventing an NPE - //FIXME if an entity has subclasses annotated @MappedSuperclass wo sub @Entity this is wrong superclassState.setHasSiblings( true ); final InheritanceState superEntityState = getInheritanceStateOfSuperEntity( clazz, inheritanceStatePerClass ); state.setHasParents( superEntityState != null ); @@ -2493,7 +2486,12 @@ public final class AnnotationBinder { state.setType( superclassState.getType() ); } } - inheritanceStatePerClass.put( clazz, state ); + switch ( buildingContext.getMetadataCollector().getClassType( clazz ) ) { + case ENTITY: + case MAPPED_SUPERCLASS: + case EMBEDDABLE: + inheritanceStatePerClass.put( clazz, state ); + } } return inheritanceStatePerClass; } 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 dc033fe0da..006548d8af 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 @@ -137,6 +137,8 @@ import jakarta.persistence.UniqueConstraint; import static jakarta.persistence.AccessType.PROPERTY; import static jakarta.persistence.FetchType.EAGER; import static jakarta.persistence.FetchType.LAZY; +import static org.hibernate.boot.model.internal.AnnotatedClassType.EMBEDDABLE; +import static org.hibernate.boot.model.internal.AnnotatedClassType.NONE; import static org.hibernate.boot.model.internal.AnnotatedColumn.buildColumnFromAnnotation; import static org.hibernate.boot.model.internal.AnnotatedColumn.buildColumnFromNoAnnotation; import static org.hibernate.boot.model.internal.AnnotatedColumn.buildColumnsFromAnnotations; @@ -2126,7 +2128,7 @@ public abstract class CollectionBinder { final XClass elementClass = isPrimitive( elementType.getName() ) ? null : elementType; final AnnotatedClassType classType = annotatedElementType( isEmbedded, property, elementType ); - final boolean primitive = classType == AnnotatedClassType.NONE; + final boolean primitive = classType == NONE; if ( !primitive ) { parentPropertyHolder.startingProperty( property ); } @@ -2143,7 +2145,7 @@ public abstract class CollectionBinder { final Class> compositeUserType = resolveCompositeUserType( property, elementClass, buildingContext ); - if ( classType == AnnotatedClassType.EMBEDDABLE || compositeUserType != null ) { + if ( classType == EMBEDDABLE || compositeUserType != null ) { handleCompositeCollectionElement( collection, property, hqlOrderBy, elementClass, holder, compositeUserType ); } else { @@ -2248,7 +2250,7 @@ public abstract class CollectionBinder { XProperty property, XClass elementType) { if ( isPrimitive( elementType.getName() ) ) { - return AnnotatedClassType.NONE; + return NONE; } else { //force in case of attribute override @@ -2256,7 +2258,7 @@ public abstract class CollectionBinder { || property.isAnnotationPresent( AttributeOverrides.class ); // todo : force in the case of Convert annotation(s) with embedded paths (beyond key/value prefixes)? return isEmbedded || attributeOverride - ? AnnotatedClassType.EMBEDDABLE + ? EMBEDDABLE : buildingContext.getMetadataCollector().getClassType( elementType ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/EntityBinder.java b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/EntityBinder.java index 281f75b0bd..f087962ef8 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/EntityBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/EntityBinder.java @@ -121,6 +121,7 @@ import jakarta.persistence.SecondaryTables; import jakarta.persistence.SharedCacheMode; import jakarta.persistence.UniqueConstraint; +import static org.hibernate.boot.model.internal.AnnotatedClassType.MAPPED_SUPERCLASS; import static org.hibernate.boot.model.internal.AnnotatedDiscriminatorColumn.buildDiscriminatorColumn; import static org.hibernate.boot.model.internal.AnnotatedJoinColumn.buildInheritanceJoinColumn; import static org.hibernate.boot.model.internal.BinderHelper.getMappedSuperclassOrNull; @@ -2100,7 +2101,7 @@ public class EntityBinder { public void processComplementaryTableDefinitions(org.hibernate.annotations.Table table) { if ( table != null ) { - Table appliedTable = findTable( table.appliesTo() ); + final Table appliedTable = findTable( table.appliesTo() ); if ( !table.comment().isEmpty() ) { appliedTable.setComment( table.comment() ); } @@ -2141,11 +2142,11 @@ public class EntityBinder { return propertyAccessType; } - public void setPropertyAccessType(AccessType propertyAccessor) { + public void setPropertyAccessType(AccessType propertyAccessType) { this.propertyAccessType = getExplicitAccessType( annotatedClass ); // only set the access type if there is no explicit access type for this class - if( this.propertyAccessType == null ) { - this.propertyAccessType = propertyAccessor; + if ( this.propertyAccessType == null ) { + this.propertyAccessType = propertyAccessType; } } @@ -2174,7 +2175,7 @@ public class EntityBinder { XClass classToProcess = annotatedClass.getSuperclass(); while ( classToProcess != null ) { final AnnotatedClassType classType = context.getMetadataCollector().getClassType( classToProcess ); - if ( classType == AnnotatedClassType.MAPPED_SUPERCLASS ) { + if ( classType == MAPPED_SUPERCLASS ) { bindFilters( classToProcess ); } else { diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/MapBinder.java b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/MapBinder.java index 779cc2cd21..398f039295 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/MapBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/MapBinder.java @@ -50,6 +50,7 @@ import jakarta.persistence.MapKeyJoinColumn; import jakarta.persistence.MapKeyJoinColumns; import static org.hibernate.boot.model.internal.AnnotatedClassType.EMBEDDABLE; +import static org.hibernate.boot.model.internal.AnnotatedClassType.NONE; import static org.hibernate.boot.model.internal.BinderHelper.findPropertyByName; import static org.hibernate.boot.model.internal.BinderHelper.isPrimitive; import static org.hibernate.boot.model.internal.PropertyHolderBuilder.buildPropertyHolder; @@ -207,7 +208,7 @@ public class MapBinder extends CollectionBinder { String mapKeyType, XClass keyClass) { if ( isPrimitive( mapKeyType ) ) { - return AnnotatedClassType.NONE; + return NONE; } else { // force in case of attribute override naming the key diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/annotations/AnnotationMetadataSourceProcessorImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/annotations/AnnotationMetadataSourceProcessorImpl.java index e948391736..e00eb0fdf7 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/annotations/AnnotationMetadataSourceProcessorImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/source/internal/annotations/AnnotationMetadataSourceProcessorImpl.java @@ -12,7 +12,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -import org.hibernate.annotations.Imported; import org.hibernate.annotations.common.reflection.MetadataProviderInjector; import org.hibernate.annotations.common.reflection.ReflectionManager; import org.hibernate.annotations.common.reflection.XClass; @@ -37,9 +36,7 @@ import org.jboss.logging.Logger; import jakarta.persistence.AttributeConverter; import jakarta.persistence.Converter; -import jakarta.persistence.Embeddable; import jakarta.persistence.Entity; -import jakarta.persistence.MappedSuperclass; /** * @author Steve Ebersole @@ -114,14 +111,8 @@ public class AnnotationMetadataSourceProcessorImpl implements MetadataSourceProc //noinspection unchecked converterRegistry.addAttributeConverter( (Class>) annotatedClass ); } - else if ( xClass.isAnnotationPresent( Entity.class ) - || xClass.isAnnotationPresent( MappedSuperclass.class ) - || xClass.isAnnotationPresent( Embeddable.class ) - || xClass.isAnnotationPresent( Imported.class ) ) { - xClasses.add( xClass ); - } else { - log.debugf( "Encountered a non-categorized annotated class [%s]; ignoring", annotatedClass.getName() ); + xClasses.add( xClass ); } } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/manytomany/GroupWithSet.java b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/manytomany/GroupWithSet.java index 73e2c155ba..6d86dfe5db 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/manytomany/GroupWithSet.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/manytomany/GroupWithSet.java @@ -27,7 +27,6 @@ import org.hibernate.annotations.WhereJoinTable; */ @Entity @Table(name = "tbl_group") -@FilterDef(name="Groupfilter") public class GroupWithSet { private Integer id; private Set permissions;