HHH-15099 - Improve handling of associations marked with @NotFound

- support for NotFound on logical 1-1 defined on JoinTable
This commit is contained in:
Steve Ebersole 2022-03-04 23:17:43 -06:00
parent ed5831f482
commit 82feac6bd3
6 changed files with 28 additions and 9 deletions

View File

@ -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() );
}

View File

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

View File

@ -29,6 +29,5 @@ public class SecondaryTableSecondPass implements SecondPass {
public void doSecondPass(Map<String, PersistentClass> persistentClasses) throws MappingException {
entityBinder.finalSecondaryTableBinding( propertyHolder );
}
}

View File

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

View File

@ -5,6 +5,7 @@
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
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();

View File

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