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 641afbcf84
commit bdb2906a94
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.type.descriptor.java.JavaType;
import jakarta.persistence.ConstraintMode;
import jakarta.persistence.Embeddable;
import jakarta.persistence.EmbeddedId;
import jakarta.persistence.FetchType;
import jakarta.persistence.ForeignKey;
import jakarta.persistence.ManyToOne;
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.HCANNHelper.findAnnotation;
import static org.hibernate.internal.util.StringHelper.isEmpty;
@ -1124,6 +1128,17 @@ public class BinderHelper {
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
*

View File

@ -31,7 +31,6 @@ import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import org.hibernate.annotations.Filter;
import org.hibernate.annotations.Filters;
import org.hibernate.annotations.ForeignKey;
import org.hibernate.annotations.HQLSelect;
import org.hibernate.annotations.Immutable;
import org.hibernate.annotations.Loader;
@ -117,6 +116,7 @@ import jakarta.persistence.ConstraintMode;
import jakarta.persistence.DiscriminatorColumn;
import jakarta.persistence.DiscriminatorValue;
import jakarta.persistence.Entity;
import jakarta.persistence.ForeignKey;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.IdClass;
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.hasToOneAnnotation;
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.toAliasTableMap;
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) {
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 PrimaryKeyJoinColumns pkJoinColumns = clazzToProcess.getAnnotation( PrimaryKeyJoinColumns.class );
final boolean noConstraintByDefault = context.getBuildingOptions().isNoConstraintByDefault();
if ( pkJoinColumns != null && ( pkJoinColumns.foreignKey().value() == ConstraintMode.NO_CONSTRAINT
|| pkJoinColumns.foreignKey().value() == ConstraintMode.PROVIDER_DEFAULT && noConstraintByDefault ) ) {
// don't apply a constraint based on ConstraintMode
if ( pkJoinColumn != null && noConstraint( pkJoinColumn.foreignKey(), noConstraintByDefault )
|| pkJoinColumns != null && noConstraint( pkJoinColumns.foreignKey(), noConstraintByDefault ) ) {
key.disableForeignKey();
}
else if ( pkJoinColumns != null && isNotEmpty( pkJoinColumns.foreignKey().name() ) ) {
key.setForeignKeyName( pkJoinColumns.foreignKey().name() );
if ( !pkJoinColumns.foreignKey().foreignKeyDefinition().isEmpty() ) {
key.setForeignKeyDefinition( pkJoinColumns.foreignKey().foreignKeyDefinition() );
else {
final org.hibernate.annotations.ForeignKey fk =
clazzToProcess.getAnnotation( org.hibernate.annotations.ForeignKey.class );
if ( fk != null && isNotEmpty( fk.name() ) ) {
key.setForeignKeyName( fk.name() );
}
}
else if ( pkJoinColumn != null && ( pkJoinColumn.foreignKey().value() == ConstraintMode.NO_CONSTRAINT
|| pkJoinColumn.foreignKey().value() == ConstraintMode.PROVIDER_DEFAULT && noConstraintByDefault ) ) {
// don't apply a constraint based on ConstraintMode
else {
final ForeignKey foreignKey = clazzToProcess.getAnnotation( ForeignKey.class );
if ( noConstraint( foreignKey, noConstraintByDefault ) ) {
key.disableForeignKey();
}
else if ( pkJoinColumn != null && isNotEmpty( pkJoinColumn.foreignKey().name() ) ) {
key.setForeignKeyName( pkJoinColumn.foreignKey().name() );
if ( !pkJoinColumn.foreignKey().foreignKeyDefinition().isEmpty() ) {
key.setForeignKeyDefinition( pkJoinColumn.foreignKey().foreignKeyDefinition() );
else if ( foreignKey != null ) {
key.setForeignKeyName( nullIfEmpty( foreignKey.name() ) );
key.setForeignKeyDefinition( nullIfEmpty( 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.getPath;
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.util.StringHelper.isEmpty;
import static org.hibernate.internal.util.StringHelper.isNotEmpty;
@ -610,8 +611,9 @@ public class ToOneBinder {
else {
final JoinColumn joinColumn = property.getAnnotation( JoinColumn.class );
final JoinColumns joinColumns = property.getAnnotation( JoinColumns.class );
if ( joinColumn!=null && noConstraint( joinColumn.foreignKey(), context )
|| joinColumns!=null && noConstraint( joinColumns.foreignKey(), context ) ) {
final boolean noConstraintByDefault = context.getBuildingOptions().isNoConstraintByDefault();
if ( joinColumn != null && noConstraint( joinColumn.foreignKey(), noConstraintByDefault )
|| joinColumns != null && noConstraint( joinColumns.foreignKey(), noConstraintByDefault ) ) {
value.disableForeignKey();
}
else {
@ -621,13 +623,16 @@ public class ToOneBinder {
value.setForeignKeyName( fk.name() );
}
else {
if ( noConstraint( foreignKey, context ) ) {
if ( noConstraint( foreignKey, noConstraintByDefault ) ) {
value.disableForeignKey();
}
else if ( foreignKey != null ) {
value.setForeignKeyName( nullIfEmpty( foreignKey.name() ) );
value.setForeignKeyDefinition( nullIfEmpty( foreignKey.foreignKeyDefinition() ) );
}
else if ( noConstraintByDefault ) {
value.disableForeignKey();
}
else if ( joinColumns != null ) {
value.setForeignKeyName( nullIfEmpty( joinColumns.foreignKey().name() ) );
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) {
return isDefault( targetEntity, context )
? propertyData.getClassOrElementName()