diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/DialectOverride.java b/hibernate-core/src/main/java/org/hibernate/annotations/DialectOverride.java new file mode 100644 index 0000000000..224349a6cb --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/annotations/DialectOverride.java @@ -0,0 +1,300 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.annotations; + +import org.hibernate.Incubating; +import org.hibernate.dialect.Dialect; + +import java.lang.annotation.Annotation; +import java.lang.annotation.Repeatable; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +import static java.lang.Integer.MAX_VALUE; +import static java.lang.Integer.MIN_VALUE; +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * Allows certain annotations to be overridden in a given SQL {@link Dialect}. + * + * @author Gavin King + */ +@Incubating +public interface DialectOverride { + + /** + * Identifies a database version. + * + * @see org.hibernate.dialect.DatabaseVersion + */ + @Retention(RUNTIME) + @interface Version { + int major(); + int minor() default 0; + } + + /** + * Specializes a {@link org.hibernate.annotations.Check} + * in a certain dialect. + */ + @Target({METHOD, FIELD, TYPE}) + @Retention(RUNTIME) + @Repeatable(Checks.class) + @OverridesAnnotation(org.hibernate.annotations.Check.class) + @interface Check { + /** + * The {@link Dialect} in which this override applies. + */ + Class dialect(); + Version before() default @Version(major = MAX_VALUE); + Version sameOrAfter() default @Version(major = MIN_VALUE); + + org.hibernate.annotations.Check override(); + } + @Target({METHOD, FIELD, TYPE}) + @Retention(RUNTIME) + @interface Checks { + Check[] value(); + } + + /** + * Specializes an {@link org.hibernate.annotations.OrderBy} + * in a certain dialect. + */ + @Target({METHOD, FIELD}) + @Retention(RUNTIME) + @Repeatable(OrderBys.class) + @OverridesAnnotation(org.hibernate.annotations.OrderBy.class) + @interface OrderBy { + /** + * The {@link Dialect} in which this override applies. + */ + Class dialect(); + Version before() default @Version(major = MAX_VALUE); + Version sameOrAfter() default @Version(major = MIN_VALUE); + + org.hibernate.annotations.OrderBy override(); + } + @Target({METHOD, FIELD}) + @Retention(RUNTIME) + @interface OrderBys { + OrderBy[] value(); + } + + /** + * Specializes a {@link org.hibernate.annotations.ColumnDefault} + * in a certain dialect. + */ + @Target({METHOD, FIELD}) + @Retention(RUNTIME) + @Repeatable(ColumnDefaults.class) + @OverridesAnnotation(org.hibernate.annotations.ColumnDefault.class) + @interface ColumnDefault { + /** + * The {@link Dialect} in which this override applies. + */ + Class dialect(); + Version before() default @Version(major = MAX_VALUE); + Version sameOrAfter() default @Version(major = MIN_VALUE); + + org.hibernate.annotations.ColumnDefault override(); + } + @Target({METHOD, FIELD}) + @Retention(RUNTIME) + @interface ColumnDefaults { + ColumnDefault[] value(); + } + + /** + * Specializes a {@link org.hibernate.annotations.GeneratedColumn} + * in a certain dialect. + */ + @Target({METHOD, FIELD}) + @Retention(RUNTIME) + @Repeatable(GeneratedColumns.class) + @OverridesAnnotation(org.hibernate.annotations.GeneratedColumn.class) + @interface GeneratedColumn { + /** + * The {@link Dialect} in which this override applies. + */ + Class dialect(); + Version before() default @Version(major = MAX_VALUE); + Version sameOrAfter() default @Version(major = MIN_VALUE); + + org.hibernate.annotations.GeneratedColumn override(); + } + @Target({METHOD, FIELD}) + @Retention(RUNTIME) + @interface GeneratedColumns { + GeneratedColumn[] value(); + } + + /** + * Specializes a {@link org.hibernate.annotations.DiscriminatorFormula} + * in a certain dialect. + */ + @Target(TYPE) + @Retention(RUNTIME) + @Repeatable(DiscriminatorFormulas.class) + @OverridesAnnotation(org.hibernate.annotations.DiscriminatorFormula.class) + @interface DiscriminatorFormula { + /** + * The {@link Dialect} in which this override applies. + */ + Class dialect(); + Version before() default @Version(major = MAX_VALUE); + Version sameOrAfter() default @Version(major = MIN_VALUE); + + org.hibernate.annotations.DiscriminatorFormula override(); + } + @Target(TYPE) + @Retention(RUNTIME) + @interface DiscriminatorFormulas { + DiscriminatorFormula[] value(); + } + + /** + * Specializes a {@link org.hibernate.annotations.Formula} + * in a certain dialect. + */ + @Target({METHOD, FIELD}) + @Retention(RUNTIME) + @Repeatable(Formulas.class) + @OverridesAnnotation(org.hibernate.annotations.Formula.class) + @interface Formula { + /** + * The {@link Dialect} in which this override applies. + */ + Class dialect(); + Version before() default @Version(major = MAX_VALUE); + Version sameOrAfter() default @Version(major = MIN_VALUE); + + org.hibernate.annotations.Formula override(); + } + @Target({METHOD, FIELD}) + @Retention(RUNTIME) + @interface Formulas { + Formula[] value(); + } + + /** + * Specializes a {@link org.hibernate.annotations.JoinFormula} + * in a certain dialect. + */ + @Target({METHOD, FIELD}) + @Retention(RUNTIME) + @OverridesAnnotation(org.hibernate.annotations.JoinFormula.class) + @interface JoinFormula { + /** + * The {@link Dialect} in which this override applies. + */ + Class dialect(); + Version before() default @Version(major = MAX_VALUE); + Version sameOrAfter() default @Version(major = MIN_VALUE); + + org.hibernate.annotations.JoinFormula override(); + } + @Target({METHOD, FIELD}) + @Retention(RUNTIME) + @interface JoinFormulas { + JoinFormula[] value(); + } + + /** + * Specializes a {@link org.hibernate.annotations.Where} + * in a certain dialect. + */ + @Target({METHOD, FIELD, TYPE}) + @Retention(RUNTIME) + @OverridesAnnotation(org.hibernate.annotations.Where.class) + @interface Where { + /** + * The {@link Dialect} in which this override applies. + */ + Class dialect(); + Version before() default @Version(major = MAX_VALUE); + Version sameOrAfter() default @Version(major = MIN_VALUE); + + org.hibernate.annotations.Where override(); + } + @Target({METHOD, FIELD, TYPE}) + @Retention(RUNTIME) + @interface Wheres { + Where[] value(); + } + + /** + * Specializes {@link org.hibernate.annotations.Filters} + * in a certain dialect. + */ + @Target({METHOD, FIELD, TYPE}) + @Retention(RUNTIME) + @Repeatable(FilterOverrides.class) + @OverridesAnnotation(org.hibernate.annotations.Filters.class) + @interface Filters { + /** + * The {@link Dialect} in which this override applies. + */ + Class dialect(); + Version before() default @Version(major = MAX_VALUE); + Version sameOrAfter() default @Version(major = MIN_VALUE); + + org.hibernate.annotations.Filters override(); + } + @Target({METHOD, FIELD, TYPE}) + @Retention(RUNTIME) + @interface FilterOverrides { + Filters[] value(); + } + + /** + * Specializes {@link org.hibernate.annotations.FilterDefs} + * in a certain dialect. + */ + @Target({PACKAGE, TYPE}) + @Retention(RUNTIME) + @Repeatable(FilterDefOverrides.class) + @OverridesAnnotation(org.hibernate.annotations.FilterDefs.class) + @interface FilterDefs { + /** + * The {@link Dialect} in which this override applies. + */ + Class dialect(); + Version before() default @Version(major = MAX_VALUE); + Version sameOrAfter() default @Version(major = MIN_VALUE); + + org.hibernate.annotations.FilterDefs override(); + } + @Target({PACKAGE, TYPE}) + @Retention(RUNTIME) + @interface FilterDefOverrides { + FilterDefs[] value(); + } + + /** + * Marks an annotation type as a dialect-specific override for + * some other annotation type. + *

+ * The marked annotation must have the following members: + *

+ */ + @Target({ANNOTATION_TYPE}) + @Retention(RUNTIME) + @interface OverridesAnnotation { + /** + * The class of the annotation that is overridden. + */ + Class value(); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/AnnotatedColumn.java b/hibernate-core/src/main/java/org/hibernate/cfg/AnnotatedColumn.java index 3782cdf9ff..4dcce1956c 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/AnnotatedColumn.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/AnnotatedColumn.java @@ -37,6 +37,8 @@ import org.hibernate.mapping.Table; import org.jboss.logging.Logger; +import static org.hibernate.cfg.AnnotationBinder.getOverridableAnnotation; + /** * Wrap state of an EJB3 @Column annotation * and build the Hibernate column mapping element @@ -672,7 +674,7 @@ public class AnnotatedColumn { private void applyColumnDefault(PropertyData inferredData, int length) { final XProperty xProperty = inferredData.getProperty(); if ( xProperty != null ) { - ColumnDefault columnDefaultAnn = xProperty.getAnnotation( ColumnDefault.class ); + ColumnDefault columnDefaultAnn = getOverridableAnnotation( xProperty, ColumnDefault.class, context ); if ( columnDefaultAnn != null ) { if (length!=1) { throw new MappingException("@ColumnDefault may only be applied to single-column mappings"); @@ -690,7 +692,7 @@ public class AnnotatedColumn { private void applyGeneratedAs(PropertyData inferredData, int length) { final XProperty xProperty = inferredData.getProperty(); if ( xProperty != null ) { - GeneratedColumn generatedAnn = xProperty.getAnnotation( GeneratedColumn.class ); + GeneratedColumn generatedAnn = getOverridableAnnotation( xProperty, GeneratedColumn.class, context ); if ( generatedAnn != null ) { if (length!=1) { throw new MappingException("@GeneratedColumn may only be applied to single-column mappings"); @@ -708,7 +710,7 @@ public class AnnotatedColumn { private void applyCheckConstraint(PropertyData inferredData, int length) { final XProperty xProperty = inferredData.getProperty(); if ( xProperty != null ) { - Check columnDefaultAnn = xProperty.getAnnotation( Check.class ); + Check columnDefaultAnn = AnnotationBinder.getOverridableAnnotation( xProperty, Check.class, context ); if ( columnDefaultAnn != null ) { if (length!=1) { throw new MappingException("@Check may only be applied to single-column mappings (use a table-level @Check)"); diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationBinder.java b/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationBinder.java index e31e027ad9..21a5599b1f 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationBinder.java @@ -7,8 +7,10 @@ package org.hibernate.cfg; import java.lang.annotation.Annotation; +import java.lang.annotation.Repeatable; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Member; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -20,6 +22,7 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; +import java.util.stream.Stream; import org.hibernate.AnnotationException; import org.hibernate.AssertionFailure; @@ -36,6 +39,7 @@ import org.hibernate.annotations.CollectionTypeRegistration; import org.hibernate.annotations.CollectionTypeRegistrations; import org.hibernate.annotations.Columns; import org.hibernate.annotations.Comment; +import org.hibernate.annotations.DialectOverride.OverridesAnnotation; import org.hibernate.annotations.DiscriminatorFormula; import org.hibernate.annotations.DiscriminatorOptions; import org.hibernate.annotations.EmbeddableInstantiatorRegistration; @@ -47,6 +51,7 @@ import org.hibernate.annotations.Filter; import org.hibernate.annotations.FilterDef; import org.hibernate.annotations.FilterDefs; import org.hibernate.annotations.Filters; +import org.hibernate.annotations.DialectOverride; import org.hibernate.annotations.ForeignKey; import org.hibernate.annotations.Formula; import org.hibernate.annotations.GenericGenerator; @@ -104,6 +109,7 @@ import org.hibernate.cfg.annotations.PropertyBinder; import org.hibernate.cfg.annotations.QueryBinder; import org.hibernate.cfg.annotations.TableBinder; import org.hibernate.cfg.internal.NullableDiscriminatorColumnSecondPass; +import org.hibernate.dialect.Dialect; import org.hibernate.engine.OptimisticLockStyle; import org.hibernate.engine.spi.FilterDefinition; import org.hibernate.id.IdentifierGenerator; @@ -632,15 +638,15 @@ public final class AnnotationBinder { entityBinder.setProxy( clazzToProcess.getAnnotation( Proxy.class ) ); entityBinder.setBatchSize( clazzToProcess.getAnnotation( BatchSize.class ) ); - entityBinder.setWhere( clazzToProcess.getAnnotation( Where.class ) ); + entityBinder.setWhere( getOverridableAnnotation( clazzToProcess, Where.class, context ) ); applyCacheSettings( entityBinder, clazzToProcess, context ); - bindFilters( clazzToProcess, entityBinder, context ); + bindFiltersAndFilterDefs( clazzToProcess, entityBinder, context ); entityBinder.bindEntity(); if ( inheritanceState.hasTable() ) { - Check checkAnn = clazzToProcess.getAnnotation( Check.class ); + Check checkAnn = getOverridableAnnotation( clazzToProcess, Check.class, context ); String constraints = checkAnn == null ? null : checkAnn.constraints(); @@ -842,6 +848,57 @@ public final class AnnotationBinder { bindCallbacks( clazzToProcess, persistentClass, context ); } + public static T getOverridableAnnotation( + XAnnotatedElement element, + Class annotationType, + MetadataBuildingContext context) { + Dialect dialect = context.getMetadataCollector().getDatabase().getDialect(); + Iterator annotations = + Arrays.stream( element.getAnnotations() ) + .flatMap(annotation -> { + try { + Method value = annotation.annotationType().getDeclaredMethod("value"); + Class returnType = value.getReturnType(); + if ( returnType.isArray() + && returnType.getComponentType().isAnnotationPresent(Repeatable.class) + && returnType.getComponentType().isAnnotationPresent(OverridesAnnotation.class) ) { + return Stream.of( (Annotation[]) value.invoke(annotation) ); + } + } + catch (NoSuchMethodException ignored) {} + catch (Exception e) { + throw new AssertionFailure("could not read @DialectOverride annotation", e); + } + return Stream.of(annotation); + }).iterator(); + while ( annotations.hasNext() ) { + Annotation annotation = annotations.next(); + Class type = annotation.annotationType(); + OverridesAnnotation overridesAnnotation = type.getAnnotation(OverridesAnnotation.class); + if ( overridesAnnotation != null + && overridesAnnotation.value().equals(annotationType) ) { + try { + Class overrideDialect = (Class) + type.getDeclaredMethod("dialect").invoke(annotation); + if ( overrideDialect.isAssignableFrom( dialect.getClass() ) ) { + DialectOverride.Version before = (DialectOverride.Version) + type.getDeclaredMethod("before").invoke(annotation); + DialectOverride.Version sameOrAfter = (DialectOverride.Version) + type.getDeclaredMethod("sameOrAfter").invoke(annotation); + if ( dialect.getVersion().isBefore( before.major(), before.minor() ) + && dialect.getVersion().isSameOrAfter( sameOrAfter.major(), sameOrAfter.minor() ) ) { + return (T) type.getDeclaredMethod("override").invoke(annotation); + } + } + } + catch (Exception e) { + throw new AssertionFailure("could not read @DialectOverride annotation", e); + } + } + } + return element.getAnnotation( annotationType ); + } + private static void handleTypeDescriptorRegistrations(XAnnotatedElement annotatedElement, MetadataBuildingContext context) { final ManagedBeanRegistry managedBeanRegistry = context.getBootstrapContext() .getServiceRegistry() @@ -958,9 +1015,7 @@ public final class AnnotationBinder { ? discAnn.discriminatorType() : DiscriminatorType.STRING; - DiscriminatorFormula discFormulaAnn = clazzToProcess.getAnnotation( - DiscriminatorFormula.class - ); + DiscriminatorFormula discFormulaAnn = getOverridableAnnotation( clazzToProcess, DiscriminatorFormula.class, context ); if ( isRoot ) { discriminatorColumn = AnnotatedDiscriminatorColumn.buildDiscriminatorColumn( discriminatorType, @@ -1402,18 +1457,18 @@ public final class AnnotationBinder { * on the MappedSuperclass(s) in the inheritance hierarchy */ - private static void bindFilters( + private static void bindFiltersAndFilterDefs( XClass annotatedClass, EntityBinder entityBinder, MetadataBuildingContext context) { - bindFilters( annotatedClass, entityBinder ); + bindFilters( annotatedClass, entityBinder, context ); XClass classToProcess = annotatedClass.getSuperclass(); while ( classToProcess != null ) { AnnotatedClassType classType = context.getMetadataCollector().getClassType( classToProcess ); if ( AnnotatedClassType.EMBEDDABLE_SUPERCLASS.equals( classType ) ) { - bindFilters( classToProcess, entityBinder ); + bindFilters( classToProcess, entityBinder, context ); } else { break; @@ -1423,9 +1478,8 @@ public final class AnnotationBinder { } - private static void bindFilters(XAnnotatedElement annotatedElement, EntityBinder entityBinder) { - - Filters filtersAnn = annotatedElement.getAnnotation( Filters.class ); + private static void bindFilters(XAnnotatedElement annotatedElement, EntityBinder entityBinder, MetadataBuildingContext context) { + Filters filtersAnn = getOverridableAnnotation( annotatedElement, Filters.class, context ); if ( filtersAnn != null ) { for ( Filter filter : filtersAnn.value() ) { entityBinder.addFilter(filter); @@ -1440,7 +1494,7 @@ public final class AnnotationBinder { private static void bindFilterDefs(XAnnotatedElement annotatedElement, MetadataBuildingContext context) { FilterDef defAnn = annotatedElement.getAnnotation( FilterDef.class ); - FilterDefs defsAnn = annotatedElement.getAnnotation( FilterDefs.class ); + FilterDefs defsAnn = getOverridableAnnotation( annotatedElement, FilterDefs.class, context ); if ( defAnn != null ) { bindFilterDef( defAnn, context ); } @@ -2038,7 +2092,7 @@ public final class AnnotationBinder { collectionBinder.setBatchSize( property.getAnnotation( BatchSize.class ) ); collectionBinder.setJpaOrderBy( property.getAnnotation( jakarta.persistence.OrderBy.class ) ); - collectionBinder.setSqlOrderBy( property.getAnnotation( OrderBy.class ) ); + collectionBinder.setSqlOrderBy( getOverridableAnnotation( property, OrderBy.class, context ) ); collectionBinder.setNaturalSort( property.getAnnotation( SortNatural.class ) ); collectionBinder.setComparatorSort( property.getAnnotation( SortComparator.class ) ); @@ -2060,11 +2114,10 @@ public final class AnnotationBinder { inferredData, "element" ); Comment comment = property.getAnnotation(Comment.class); - if ( property.isAnnotationPresent( Column.class ) || property.isAnnotationPresent( - Formula.class - ) ) { + if ( property.isAnnotationPresent( Column.class ) + || property.isAnnotationPresent( Formula.class ) ) { Column ann = property.getAnnotation( Column.class ); - Formula formulaAnn = property.getAnnotation( Formula.class ); + Formula formulaAnn = getOverridableAnnotation( property, Formula.class, context ); elementColumns = AnnotatedColumn.buildColumnFromAnnotation( new Column[] { ann }, formulaAnn, @@ -3371,8 +3424,8 @@ public final class AnnotationBinder { EntityBinder entityBinder, boolean isIdentifierMapper, MetadataBuildingContext buildingContext) { - org.hibernate.annotations.Any anyAnn = inferredData - .getProperty() + XProperty property = inferredData.getProperty(); + org.hibernate.annotations.Any anyAnn = property .getAnnotation( org.hibernate.annotations.Any.class ); if ( anyAnn == null ) { throw new AssertionFailure( @@ -3381,8 +3434,8 @@ public final class AnnotationBinder { ); } - final Column discriminatorColumnAnn = inferredData.getProperty().getAnnotation( Column.class ); - final Formula discriminatorFormulaAnn = inferredData.getProperty().getAnnotation( Formula.class ); + final Column discriminatorColumnAnn = property.getAnnotation( Column.class ); + final Formula discriminatorFormulaAnn = getOverridableAnnotation( property, Formula.class, buildingContext ); boolean lazy = ( anyAnn.fetch() == FetchType.LAZY ); Any value = BinderHelper.buildAnyValue( diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/BinderHelper.java b/hibernate-core/src/main/java/org/hibernate/cfg/BinderHelper.java index ebafb6e1ac..af37a785f7 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/BinderHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/BinderHelper.java @@ -816,7 +816,7 @@ public class BinderHelper { value.setLazy( lazy ); value.setCascadeDeleteEnabled( cascadeOnDelete ); - final BasicValueBinder discriminatorValueBinder = new BasicValueBinder( BasicValueBinder.Kind.ANY_DISCRIMINATOR, context ); + final BasicValueBinder discriminatorValueBinder = new BasicValueBinder<>( BasicValueBinder.Kind.ANY_DISCRIMINATOR, context ); final AnnotatedColumn[] discriminatorColumns = AnnotatedColumn.buildColumnFromAnnotation( new jakarta.persistence.Column[] { discriminatorColumn }, diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/ColumnsBuilder.java b/hibernate-core/src/main/java/org/hibernate/cfg/ColumnsBuilder.java index a209d6acaf..5dbe45450d 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/ColumnsBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/ColumnsBuilder.java @@ -28,6 +28,8 @@ import org.hibernate.cfg.annotations.EntityBinder; import org.hibernate.cfg.annotations.Nullability; import org.hibernate.internal.util.StringHelper; +import static org.hibernate.cfg.AnnotationBinder.getOverridableAnnotation; + /** * Do the initial discovery of columns metadata and apply defaults. * Also hosts some convenient methods related to column processing @@ -76,7 +78,7 @@ class ColumnsBuilder { Comment comment = property.getAnnotation(Comment.class); if ( property.isAnnotationPresent( Column.class ) || property.isAnnotationPresent( Formula.class ) ) { Column ann = property.getAnnotation( Column.class ); - Formula formulaAnn = property.getAnnotation( Formula.class ); + Formula formulaAnn = getOverridableAnnotation( property, Formula.class, buildingContext ); columns = AnnotatedColumn.buildColumnFromAnnotation( new Column[] { ann }, formulaAnn, @@ -249,7 +251,7 @@ class ColumnsBuilder { } if (property.isAnnotationPresent( JoinFormula.class)) { - JoinFormula ann = property.getAnnotation( JoinFormula.class ); + JoinFormula ann = getOverridableAnnotation( property, JoinFormula.class, buildingContext ); AnnotatedJoinColumn[] annotatedJoinColumns = new AnnotatedJoinColumn[1]; annotatedJoinColumns[0] = AnnotatedJoinColumn.buildJoinFormula( ann, diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java index c5085edb9f..d6ba955f13 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java @@ -131,6 +131,7 @@ import jakarta.persistence.OneToMany; import jakarta.persistence.OrderColumn; import static jakarta.persistence.AccessType.PROPERTY; +import static org.hibernate.cfg.AnnotationBinder.getOverridableAnnotation; import static org.hibernate.cfg.BinderHelper.toAliasEntityMap; import static org.hibernate.cfg.BinderHelper.toAliasTableMap; @@ -1175,7 +1176,7 @@ public abstract class CollectionBinder { toAliasTableMap(simpleFilter.aliases()), toAliasEntityMap(simpleFilter.aliases())); } } - Filters filters = property.getAnnotation( Filters.class ); + Filters filters = getOverridableAnnotation( property, Filters.class, buildingContext ); if ( filters != null ) { for (Filter filter : filters.value()) { if ( hasAssociationTable ) { @@ -1237,12 +1238,12 @@ public abstract class CollectionBinder { // for many-to-many e.g., @ManyToMany @Where(clause="...") public Set getRatings(); String whereOnClassClause = null; if ( useEntityWhereClauseForCollections && property.getElementClass() != null ) { - Where whereOnClass = property.getElementClass().getAnnotation( Where.class ); + Where whereOnClass = getOverridableAnnotation( property.getElementClass(), Where.class, getBuildingContext() ); if ( whereOnClass != null ) { whereOnClassClause = whereOnClass.clause(); } } - Where whereOnCollection = property.getAnnotation( Where.class ); + Where whereOnCollection = getOverridableAnnotation( property, Where.class, getBuildingContext() ); String whereOnCollectionClause = null; if ( whereOnCollection != null ) { whereOnCollectionClause = whereOnCollection.clause(); @@ -1720,8 +1721,9 @@ public abstract class CollectionBinder { buildingContext.getBootstrapContext().getReflectionManager() ); - final jakarta.persistence.Column discriminatorColumnAnn = inferredData.getProperty().getAnnotation( jakarta.persistence.Column.class ); - final Formula discriminatorFormulaAnn = inferredData.getProperty().getAnnotation( Formula.class ); + XProperty prop = inferredData.getProperty(); + final jakarta.persistence.Column discriminatorColumnAnn = prop.getAnnotation( jakarta.persistence.Column.class ); + final Formula discriminatorFormulaAnn = getOverridableAnnotation( prop, Formula.class, buildingContext ); //override the table for (AnnotatedColumn column : inverseJoinColumns) { diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/IdBagBinder.java b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/IdBagBinder.java index 07896b9819..e6b03fb516 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/IdBagBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/IdBagBinder.java @@ -89,7 +89,7 @@ public class IdBagBinder extends BagBinder { Nullability.FORCED_NOT_NULL, propertyHolder, propertyData, - Collections.EMPTY_MAP, + Collections.emptyMap(), buildingContext );