introduce the @DialectOverride annotation

for overriding certain mapping annotations that specify native SQL
This commit is contained in:
Gavin King 2022-01-09 13:48:00 +01:00
parent a9ddebf643
commit 8aa0665731
7 changed files with 393 additions and 34 deletions

View File

@ -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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
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<? extends Dialect> 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<? extends Dialect> 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<? extends Dialect> 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<? extends Dialect> 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<? extends Dialect> 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<? extends Dialect> 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<? extends Dialect> 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<? extends Dialect> 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<? extends Dialect> 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<? extends Dialect> 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.
* <p>
* The marked annotation must have the following members:
* <ul>
* <li>{@code Class<? extends Dialect> dialect()},
* <li>{@code Version before()},
* <li>{@code Version sameOrAfter()}, and
* <li>{@code A override()}, where {@code A} is the type
* of annotation which the marked annotation overrides.
* </ul>
*/
@Target({ANNOTATION_TYPE})
@Retention(RUNTIME)
@interface OverridesAnnotation {
/**
* The class of the annotation that is overridden.
*/
Class<? extends Annotation> value();
}
}

View File

@ -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)");

View File

@ -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 extends Annotation> T getOverridableAnnotation(
XAnnotatedElement element,
Class<T> annotationType,
MetadataBuildingContext context) {
Dialect dialect = context.getMetadataCollector().getDatabase().getDialect();
Iterator<Annotation> 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<? extends Annotation> type = annotation.annotationType();
OverridesAnnotation overridesAnnotation = type.getAnnotation(OverridesAnnotation.class);
if ( overridesAnnotation != null
&& overridesAnnotation.value().equals(annotationType) ) {
try {
Class<? extends Dialect> overrideDialect = (Class<? extends Dialect>)
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(

View File

@ -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 },

View File

@ -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,

View File

@ -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<Rating> 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) {

View File

@ -89,7 +89,7 @@ public class IdBagBinder extends BagBinder {
Nullability.FORCED_NOT_NULL,
propertyHolder,
propertyData,
Collections.EMPTY_MAP,
Collections.emptyMap(),
buildingContext
);