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 389d7d80d2..243ae5f2e0 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationBinder.java @@ -2653,6 +2653,7 @@ public final class AnnotationBinder { Cascade hibernateCascade = property.getAnnotation( Cascade.class ); NotFound notFound = property.getAnnotation( NotFound.class ); NotFoundAction notFoundAction = notFound == null ? null : notFound.action(); + final boolean hasNotFoundAction = notFoundAction != null; // MapsId means the columns belong to the pk; // A @MapsId association (obviously) must be non-null when the entity is first persisted. @@ -2663,12 +2664,15 @@ public final class AnnotationBinder { // @OneToOne(optional = true) with @PKJC makes the association optional. final boolean mandatory = !ann.optional() || property.isAnnotationPresent( Id.class ) - || property.isAnnotationPresent( MapsId.class ) && notFoundAction != NotFoundAction.IGNORE; + || property.isAnnotationPresent( MapsId.class ) && !hasNotFoundAction; matchIgnoreNotFoundWithFetchType( propertyHolder.getEntityName(), property.getName(), notFoundAction, ann.fetch() ); OnDelete onDeleteAnn = property.getAnnotation( OnDelete.class ); JoinTable assocTable = propertyHolder.getJoinTable(property); if ( assocTable != null ) { Join join = propertyHolder.addJoin( assocTable, false ); + if ( hasNotFoundAction ) { + join.disableForeignKeyCreation(); + } for ( AnnotatedJoinColumn joinColumn : joinColumns) { joinColumn.setExplicitTableName( join.getTable().getName() ); } diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/OneToOneSecondPass.java b/hibernate-core/src/main/java/org/hibernate/cfg/OneToOneSecondPass.java index d50ea9ea22..af38b2636e 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/OneToOneSecondPass.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/OneToOneSecondPass.java @@ -275,6 +275,11 @@ public class OneToOneSecondPass implements SecondPass { join.setTable( originalJoin.getTable() ); join.setInverse( true ); DependantValue key = new DependantValue( buildingContext, join.getTable(), persistentClass.getIdentifier() ); + + if ( notFoundAction != null ) { + join.disableForeignKeyCreation(); + } + //TODO support @ForeignKey join.setKey( key ); join.setSequentialSelect( false ); diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/SecondaryTableSecondPass.java b/hibernate-core/src/main/java/org/hibernate/cfg/SecondaryTableSecondPass.java index 783b4dd14e..671ec17df4 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/SecondaryTableSecondPass.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/SecondaryTableSecondPass.java @@ -29,6 +29,5 @@ public class SecondaryTableSecondPass implements SecondPass { public void doSecondPass(Map persistentClasses) throws MappingException { entityBinder.finalSecondaryTableBinding( propertyHolder ); - } } diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/Join.java b/hibernate-core/src/main/java/org/hibernate/mapping/Join.java index 8cbd04dc90..7f5eac7338 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/Join.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/Join.java @@ -29,6 +29,7 @@ public class Join implements AttributeContainer, Serializable { private boolean sequentialSelect; private boolean inverse; private boolean optional; + private boolean disableForeignKeyCreation; // Custom SQL private String customSQLInsert; @@ -97,8 +98,15 @@ public class Join implements AttributeContainer, Serializable { this.persistentClass = persistentClass; } + public void disableForeignKeyCreation() { + disableForeignKeyCreation = true; + } + public void createForeignKey() { - getKey().createForeignKeyOfEntity( persistentClass.getEntityName() ); + final ForeignKey foreignKey = getKey().createForeignKeyOfEntity( persistentClass.getEntityName() ); + if ( disableForeignKeyCreation ) { + foreignKey.disableCreation(); + } } public void createPrimaryKey() { diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/KeyValue.java b/hibernate-core/src/main/java/org/hibernate/mapping/KeyValue.java index af350776fc..dc3c5329ae 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/KeyValue.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/KeyValue.java @@ -5,6 +5,7 @@ * See the lgpl.txt file in the root directory or . */ package org.hibernate.mapping; + import org.hibernate.MappingException; import org.hibernate.dialect.Dialect; import org.hibernate.id.IdentifierGenerator; @@ -37,7 +38,7 @@ public interface KeyValue extends Value { boolean isIdentityColumn(IdentifierGeneratorFactory identifierGeneratorFactory, Dialect dialect); - void createForeignKeyOfEntity(String entityName); + ForeignKey createForeignKeyOfEntity(String entityName); boolean isCascadeDeleteEnabled(); diff --git a/hibernate-core/src/main/java/org/hibernate/mapping/SimpleValue.java b/hibernate-core/src/main/java/org/hibernate/mapping/SimpleValue.java index 2d41bd7b26..9741dfaace 100644 --- a/hibernate-core/src/main/java/org/hibernate/mapping/SimpleValue.java +++ b/hibernate-core/src/main/java/org/hibernate/mapping/SimpleValue.java @@ -16,6 +16,7 @@ import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.Properties; +import jakarta.persistence.AttributeConverter; import org.hibernate.AssertionFailure; import org.hibernate.FetchMode; @@ -60,8 +61,6 @@ import org.hibernate.type.descriptor.jdbc.NationalizedTypeMappings; import org.hibernate.type.spi.TypeConfiguration; import org.hibernate.usertype.DynamicParameterizedType; -import jakarta.persistence.AttributeConverter; - /** * Any value that maps to columns. * @author Gavin King @@ -321,11 +320,14 @@ public abstract class SimpleValue implements KeyValue { public void createForeignKey() throws MappingException {} @Override - public void createForeignKeyOfEntity(String entityName) { + public ForeignKey createForeignKeyOfEntity(String entityName) { if ( isConstrained() ) { - table.createForeignKey( getForeignKeyName(), getConstraintColumns(), entityName, getForeignKeyDefinition() ) - .setCascadeDeleteEnabled(cascadeDeleteEnabled); + final ForeignKey fk = table.createForeignKey( getForeignKeyName(), getConstraintColumns(), entityName, getForeignKeyDefinition() ); + fk.setCascadeDeleteEnabled( cascadeDeleteEnabled ); + return fk; } + + return null; } @Override