HHH-17550 Respect default no-constraint setting

This commit is contained in:
Marco Belladelli 2023-12-20 11:58:43 +01:00 committed by Christian Beikov
parent d7e3217494
commit 8dc7824b1d
3 changed files with 53 additions and 39 deletions

View File

@ -62,12 +62,16 @@ import org.hibernate.mapping.ToOne;
import org.hibernate.mapping.Value; import org.hibernate.mapping.Value;
import org.hibernate.type.descriptor.java.JavaType; import org.hibernate.type.descriptor.java.JavaType;
import jakarta.persistence.ConstraintMode;
import jakarta.persistence.Embeddable; import jakarta.persistence.Embeddable;
import jakarta.persistence.EmbeddedId; import jakarta.persistence.EmbeddedId;
import jakarta.persistence.FetchType; import jakarta.persistence.FetchType;
import jakarta.persistence.ForeignKey;
import jakarta.persistence.ManyToOne; import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToOne; import jakarta.persistence.OneToOne;
import static jakarta.persistence.ConstraintMode.NO_CONSTRAINT;
import static jakarta.persistence.ConstraintMode.PROVIDER_DEFAULT;
import static org.hibernate.boot.model.internal.AnnotatedColumn.buildColumnOrFormulaFromAnnotation; import static org.hibernate.boot.model.internal.AnnotatedColumn.buildColumnOrFormulaFromAnnotation;
import static org.hibernate.boot.model.internal.HCANNHelper.findAnnotation; import static org.hibernate.boot.model.internal.HCANNHelper.findAnnotation;
import static org.hibernate.internal.util.StringHelper.isEmpty; import static org.hibernate.internal.util.StringHelper.isEmpty;
@ -1125,6 +1129,17 @@ public class BinderHelper {
return false; return false;
} }
public static boolean noConstraint(ForeignKey foreignKey, boolean noConstraintByDefault) {
if ( foreignKey == null ) {
return false;
}
else {
final ConstraintMode mode = foreignKey.value();
return mode == NO_CONSTRAINT
|| mode == PROVIDER_DEFAULT && noConstraintByDefault;
}
}
/** /**
* Extract an annotation from the package-info for the package the given class is defined in * Extract an annotation from the package-info for the package the given class is defined in
* *

View File

@ -31,7 +31,6 @@ import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate; import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.Filter; import org.hibernate.annotations.Filter;
import org.hibernate.annotations.Filters; import org.hibernate.annotations.Filters;
import org.hibernate.annotations.ForeignKey;
import org.hibernate.annotations.HQLSelect; import org.hibernate.annotations.HQLSelect;
import org.hibernate.annotations.Immutable; import org.hibernate.annotations.Immutable;
import org.hibernate.annotations.Loader; import org.hibernate.annotations.Loader;
@ -117,6 +116,7 @@ import jakarta.persistence.ConstraintMode;
import jakarta.persistence.DiscriminatorColumn; import jakarta.persistence.DiscriminatorColumn;
import jakarta.persistence.DiscriminatorValue; import jakarta.persistence.DiscriminatorValue;
import jakarta.persistence.Entity; import jakarta.persistence.Entity;
import jakarta.persistence.ForeignKey;
import jakarta.persistence.GeneratedValue; import jakarta.persistence.GeneratedValue;
import jakarta.persistence.IdClass; import jakarta.persistence.IdClass;
import jakarta.persistence.Inheritance; import jakarta.persistence.Inheritance;
@ -139,6 +139,7 @@ import static org.hibernate.boot.model.internal.BinderHelper.getMappedSuperclass
import static org.hibernate.boot.model.internal.BinderHelper.getOverridableAnnotation; import static org.hibernate.boot.model.internal.BinderHelper.getOverridableAnnotation;
import static org.hibernate.boot.model.internal.BinderHelper.hasToOneAnnotation; import static org.hibernate.boot.model.internal.BinderHelper.hasToOneAnnotation;
import static org.hibernate.boot.model.internal.BinderHelper.isDefault; import static org.hibernate.boot.model.internal.BinderHelper.isDefault;
import static org.hibernate.boot.model.internal.BinderHelper.noConstraint;
import static org.hibernate.boot.model.internal.BinderHelper.toAliasEntityMap; import static org.hibernate.boot.model.internal.BinderHelper.toAliasEntityMap;
import static org.hibernate.boot.model.internal.BinderHelper.toAliasTableMap; import static org.hibernate.boot.model.internal.BinderHelper.toAliasTableMap;
import static org.hibernate.boot.model.internal.EmbeddableBinder.fillEmbeddable; import static org.hibernate.boot.model.internal.EmbeddableBinder.fillEmbeddable;
@ -843,34 +844,38 @@ public class EntityBinder {
} }
private static void handleForeignKeys(XClass clazzToProcess, MetadataBuildingContext context, DependantValue key) { private static void handleForeignKeys(XClass clazzToProcess, MetadataBuildingContext context, DependantValue key) {
final ForeignKey foreignKey = clazzToProcess.getAnnotation( ForeignKey.class );
if ( foreignKey != null && !foreignKey.name().isEmpty() ) {
key.setForeignKeyName( foreignKey.name() );
}
else {
final PrimaryKeyJoinColumn pkJoinColumn = clazzToProcess.getAnnotation( PrimaryKeyJoinColumn.class ); final PrimaryKeyJoinColumn pkJoinColumn = clazzToProcess.getAnnotation( PrimaryKeyJoinColumn.class );
final PrimaryKeyJoinColumns pkJoinColumns = clazzToProcess.getAnnotation( PrimaryKeyJoinColumns.class ); final PrimaryKeyJoinColumns pkJoinColumns = clazzToProcess.getAnnotation( PrimaryKeyJoinColumns.class );
final boolean noConstraintByDefault = context.getBuildingOptions().isNoConstraintByDefault(); final boolean noConstraintByDefault = context.getBuildingOptions().isNoConstraintByDefault();
if ( pkJoinColumns != null && ( pkJoinColumns.foreignKey().value() == ConstraintMode.NO_CONSTRAINT if ( pkJoinColumn != null && noConstraint( pkJoinColumn.foreignKey(), noConstraintByDefault )
|| pkJoinColumns.foreignKey().value() == ConstraintMode.PROVIDER_DEFAULT && noConstraintByDefault ) ) { || pkJoinColumns != null && noConstraint( pkJoinColumns.foreignKey(), noConstraintByDefault ) ) {
// don't apply a constraint based on ConstraintMode
key.disableForeignKey(); key.disableForeignKey();
} }
else if ( pkJoinColumns != null && isNotEmpty( pkJoinColumns.foreignKey().name() ) ) { else {
key.setForeignKeyName( pkJoinColumns.foreignKey().name() ); final org.hibernate.annotations.ForeignKey fk =
if ( !pkJoinColumns.foreignKey().foreignKeyDefinition().isEmpty() ) { clazzToProcess.getAnnotation( org.hibernate.annotations.ForeignKey.class );
key.setForeignKeyDefinition( pkJoinColumns.foreignKey().foreignKeyDefinition() ); if ( fk != null && isNotEmpty( fk.name() ) ) {
key.setForeignKeyName( fk.name() );
} }
} else {
else if ( pkJoinColumn != null && ( pkJoinColumn.foreignKey().value() == ConstraintMode.NO_CONSTRAINT final ForeignKey foreignKey = clazzToProcess.getAnnotation( ForeignKey.class );
|| pkJoinColumn.foreignKey().value() == ConstraintMode.PROVIDER_DEFAULT && noConstraintByDefault ) ) { if ( noConstraint( foreignKey, noConstraintByDefault ) ) {
// don't apply a constraint based on ConstraintMode
key.disableForeignKey(); key.disableForeignKey();
} }
else if ( pkJoinColumn != null && isNotEmpty( pkJoinColumn.foreignKey().name() ) ) { else if ( foreignKey != null ) {
key.setForeignKeyName( pkJoinColumn.foreignKey().name() ); key.setForeignKeyName( nullIfEmpty( foreignKey.name() ) );
if ( !pkJoinColumn.foreignKey().foreignKeyDefinition().isEmpty() ) { key.setForeignKeyDefinition( nullIfEmpty( foreignKey.foreignKeyDefinition() ) );
key.setForeignKeyDefinition( pkJoinColumn.foreignKey().foreignKeyDefinition() ); }
else if ( noConstraintByDefault ) {
key.disableForeignKey();
}
else if ( pkJoinColumns != null ) {
key.setForeignKeyName( nullIfEmpty( pkJoinColumns.foreignKey().name() ) );
key.setForeignKeyDefinition( nullIfEmpty( pkJoinColumns.foreignKey().foreignKeyDefinition() ) );
}
else if ( pkJoinColumn != null ) {
key.setForeignKeyName( nullIfEmpty( pkJoinColumn.foreignKey().name() ) );
key.setForeignKeyDefinition( nullIfEmpty( pkJoinColumn.foreignKey().foreignKeyDefinition() ) );
} }
} }
} }

View File

@ -57,6 +57,7 @@ import static org.hibernate.boot.model.internal.BinderHelper.getCascadeStrategy;
import static org.hibernate.boot.model.internal.BinderHelper.getFetchMode; import static org.hibernate.boot.model.internal.BinderHelper.getFetchMode;
import static org.hibernate.boot.model.internal.BinderHelper.getPath; import static org.hibernate.boot.model.internal.BinderHelper.getPath;
import static org.hibernate.boot.model.internal.BinderHelper.isDefault; import static org.hibernate.boot.model.internal.BinderHelper.isDefault;
import static org.hibernate.boot.model.internal.BinderHelper.noConstraint;
import static org.hibernate.internal.CoreLogging.messageLogger; import static org.hibernate.internal.CoreLogging.messageLogger;
import static org.hibernate.internal.util.StringHelper.isEmpty; import static org.hibernate.internal.util.StringHelper.isEmpty;
import static org.hibernate.internal.util.StringHelper.isNotEmpty; import static org.hibernate.internal.util.StringHelper.isNotEmpty;
@ -610,8 +611,9 @@ public class ToOneBinder {
else { else {
final JoinColumn joinColumn = property.getAnnotation( JoinColumn.class ); final JoinColumn joinColumn = property.getAnnotation( JoinColumn.class );
final JoinColumns joinColumns = property.getAnnotation( JoinColumns.class ); final JoinColumns joinColumns = property.getAnnotation( JoinColumns.class );
if ( joinColumn!=null && noConstraint( joinColumn.foreignKey(), context ) final boolean noConstraintByDefault = context.getBuildingOptions().isNoConstraintByDefault();
|| joinColumns!=null && noConstraint( joinColumns.foreignKey(), context ) ) { if ( joinColumn != null && noConstraint( joinColumn.foreignKey(), noConstraintByDefault )
|| joinColumns != null && noConstraint( joinColumns.foreignKey(), noConstraintByDefault ) ) {
value.disableForeignKey(); value.disableForeignKey();
} }
else { else {
@ -621,13 +623,16 @@ public class ToOneBinder {
value.setForeignKeyName( fk.name() ); value.setForeignKeyName( fk.name() );
} }
else { else {
if ( noConstraint( foreignKey, context ) ) { if ( noConstraint( foreignKey, noConstraintByDefault ) ) {
value.disableForeignKey(); value.disableForeignKey();
} }
else if ( foreignKey != null ) { else if ( foreignKey != null ) {
value.setForeignKeyName( nullIfEmpty( foreignKey.name() ) ); value.setForeignKeyName( nullIfEmpty( foreignKey.name() ) );
value.setForeignKeyDefinition( nullIfEmpty( foreignKey.foreignKeyDefinition() ) ); value.setForeignKeyDefinition( nullIfEmpty( foreignKey.foreignKeyDefinition() ) );
} }
else if ( noConstraintByDefault ) {
value.disableForeignKey();
}
else if ( joinColumns != null ) { else if ( joinColumns != null ) {
value.setForeignKeyName( nullIfEmpty( joinColumns.foreignKey().name() ) ); value.setForeignKeyName( nullIfEmpty( joinColumns.foreignKey().name() ) );
value.setForeignKeyDefinition( nullIfEmpty( joinColumns.foreignKey().foreignKeyDefinition() ) ); value.setForeignKeyDefinition( nullIfEmpty( joinColumns.foreignKey().foreignKeyDefinition() ) );
@ -641,17 +646,6 @@ public class ToOneBinder {
} }
} }
private static boolean noConstraint(ForeignKey joinColumns, MetadataBuildingContext context) {
if ( joinColumns == null ) {
return false;
}
else {
final ConstraintMode mode = joinColumns.value();
return mode == NO_CONSTRAINT
|| mode == PROVIDER_DEFAULT && context.getBuildingOptions().isNoConstraintByDefault();
}
}
public static String getReferenceEntityName(PropertyData propertyData, XClass targetEntity, MetadataBuildingContext context) { public static String getReferenceEntityName(PropertyData propertyData, XClass targetEntity, MetadataBuildingContext context) {
return isDefault( targetEntity, context ) return isDefault( targetEntity, context )
? propertyData.getClassOrElementName() ? propertyData.getClassOrElementName()