HHH-15770 let you use @ColumnDefault on associations

this is very useful in combination with @OnDelete(action=SET_NULL)
This commit is contained in:
Gavin 2022-11-27 11:11:46 +01:00 committed by Gavin King
parent 76f92bd901
commit 759b68b022
8 changed files with 211 additions and 61 deletions

View File

@ -282,6 +282,7 @@ public class AnnotatedColumn {
mappingColumn.setSqlType( sqlType ); mappingColumn.setSqlType( sqlType );
mappingColumn.setUnique( unique ); mappingColumn.setUnique( unique );
mappingColumn.setCheckConstraint( checkConstraint ); mappingColumn.setCheckConstraint( checkConstraint );
mappingColumn.setDefaultValue( defaultValue );
if ( writeExpression != null ) { if ( writeExpression != null ) {
final int numberOfJdbcParams = StringHelper.count( writeExpression, '?' ); final int numberOfJdbcParams = StringHelper.count( writeExpression, '?' );
@ -766,7 +767,7 @@ public class AnnotatedColumn {
: database.getJdbcEnvironment().getIdentifierHelper().toIdentifier( column.name() ).render(); : database.getJdbcEnvironment().getIdentifierHelper().toIdentifier( column.name() ).render();
} }
private void applyColumnDefault(PropertyData inferredData, int length) { void applyColumnDefault(PropertyData inferredData, int length) {
final XProperty property = inferredData.getProperty(); final XProperty property = inferredData.getProperty();
if ( property != null ) { if ( property != null ) {
final ColumnDefault columnDefault = final ColumnDefault columnDefault =
@ -783,7 +784,7 @@ public class AnnotatedColumn {
} }
} }
private void applyGeneratedAs(PropertyData inferredData, int length) { void applyGeneratedAs(PropertyData inferredData, int length) {
final XProperty property = inferredData.getProperty(); final XProperty property = inferredData.getProperty();
if ( property != null ) { if ( property != null ) {
final GeneratedColumn generatedColumn = final GeneratedColumn generatedColumn =

View File

@ -76,15 +76,15 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
String mappedBy, String mappedBy,
AnnotatedJoinColumns parent, AnnotatedJoinColumns parent,
PropertyHolder propertyHolder, PropertyHolder propertyHolder,
String propertyName) { PropertyData inferredData) {
final String path = qualify( propertyHolder.getPath(), propertyName ); final String path = qualify( propertyHolder.getPath(), inferredData.getPropertyName() );
final JoinColumn[] overrides = propertyHolder.getOverriddenJoinColumn( path ); final JoinColumn[] overrides = propertyHolder.getOverriddenJoinColumn( path );
if ( overrides != null ) { if ( overrides != null ) {
//TODO: relax this restriction //TODO: relax this restriction
throw new AnnotationException("Property '" + path throw new AnnotationException( "Property '" + path
+ "' overrides mapping specified using '@JoinColumnOrFormula'"); + "' overrides mapping specified using '@JoinColumnOrFormula'" );
} }
return buildJoinColumn( joinColumn, null, mappedBy, parent, propertyHolder, propertyName, "" ); return buildJoinColumn( joinColumn, null, mappedBy, parent, propertyHolder, inferredData, "" );
} }
public static AnnotatedJoinColumn buildJoinFormula( public static AnnotatedJoinColumn buildJoinFormula(
@ -108,19 +108,18 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
String mappedBy, String mappedBy,
AnnotatedJoinColumns parent, AnnotatedJoinColumns parent,
PropertyHolder propertyHolder, PropertyHolder propertyHolder,
String propertyName, PropertyData inferredData,
String defaultColumnSuffix) { String defaultColumnSuffix) {
if ( joinColumn != null ) { if ( joinColumn != null ) {
if ( !isEmptyOrNullAnnotationValue( mappedBy ) ) { if ( !isEmptyOrNullAnnotationValue( mappedBy ) ) {
throw new AnnotationException( throw new AnnotationException( "Association '"
"Association '" + getRelativePath( propertyHolder, propertyName ) + getRelativePath( propertyHolder, inferredData.getPropertyName() )
+ "' is 'mappedBy' a different entity and may not explicitly specify the '@JoinColumn'" + "' is 'mappedBy' a different entity and may not explicitly specify the '@JoinColumn'" );
);
} }
return explicitJoinColumn( joinColumn, comment, parent, propertyName, defaultColumnSuffix ); return explicitJoinColumn( joinColumn, comment, parent, inferredData, defaultColumnSuffix );
} }
else { else {
return implicitJoinColumn( parent, propertyName, defaultColumnSuffix ); return implicitJoinColumn( parent, inferredData, defaultColumnSuffix );
} }
} }
@ -128,7 +127,7 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
JoinColumn joinColumn, JoinColumn joinColumn,
Comment comment, Comment comment,
AnnotatedJoinColumns parent, AnnotatedJoinColumns parent,
String propertyName, PropertyData inferredData,
String defaultColumnSuffix) { String defaultColumnSuffix) {
final AnnotatedJoinColumn column = new AnnotatedJoinColumn(); final AnnotatedJoinColumn column = new AnnotatedJoinColumn();
column.setComment( comment != null ? comment.value() : null ); column.setComment( comment != null ? comment.value() : null );
@ -136,19 +135,20 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
// column.setJoins( joins ); // column.setJoins( joins );
// column.setPropertyHolder( propertyHolder ); // column.setPropertyHolder( propertyHolder );
if ( isEmpty( column.getLogicalColumnName() ) && isNotEmpty( defaultColumnSuffix ) ) { if ( isEmpty( column.getLogicalColumnName() ) && isNotEmpty( defaultColumnSuffix ) ) {
column.setLogicalColumnName( propertyName + defaultColumnSuffix ); column.setLogicalColumnName( inferredData.getPropertyName() + defaultColumnSuffix );
} }
// column.setPropertyName( getRelativePath( propertyHolder, propertyName ) ); // column.setPropertyName( getRelativePath( propertyHolder, propertyName ) );
column.setImplicit( false ); column.setImplicit( false );
column.setParent( parent ); column.setParent( parent );
column.applyJoinAnnotation( joinColumn, null ); column.applyJoinAnnotation( joinColumn, null );
column.applyColumnDefault( inferredData, parent.getColumns().size() );
column.bind(); column.bind();
return column; return column;
} }
private static AnnotatedJoinColumn implicitJoinColumn( private static AnnotatedJoinColumn implicitJoinColumn(
AnnotatedJoinColumns parent, AnnotatedJoinColumns parent,
String propertyName, PropertyData inferredData,
String defaultColumnSuffix) { String defaultColumnSuffix) {
final AnnotatedJoinColumn column = new AnnotatedJoinColumn(); final AnnotatedJoinColumn column = new AnnotatedJoinColumn();
// column.setContext( context ); // column.setContext( context );
@ -157,13 +157,14 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
// column.setPropertyName( getRelativePath( propertyHolder, propertyName ) ); // column.setPropertyName( getRelativePath( propertyHolder, propertyName ) );
// property name + suffix is an "explicit" column name // property name + suffix is an "explicit" column name
if ( isNotEmpty( defaultColumnSuffix ) ) { if ( isNotEmpty( defaultColumnSuffix ) ) {
column.setLogicalColumnName( propertyName + defaultColumnSuffix ); column.setLogicalColumnName( inferredData.getPropertyName() + defaultColumnSuffix );
column.setImplicit( false ); column.setImplicit( false );
} }
else { else {
column.setImplicit( true ); column.setImplicit( true );
} }
column.setParent( parent ); column.setParent( parent );
column.applyColumnDefault( inferredData, parent.getColumns().size() );
column.bind(); column.bind();
return column; return column;
} }
@ -401,7 +402,7 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
static AnnotatedJoinColumn buildImplicitJoinTableJoinColumn( static AnnotatedJoinColumn buildImplicitJoinTableJoinColumn(
AnnotatedJoinColumns parent, AnnotatedJoinColumns parent,
PropertyHolder propertyHolder, PropertyHolder propertyHolder,
String propertyName) { PropertyData inferredData) {
final AnnotatedJoinColumn column = new AnnotatedJoinColumn(); final AnnotatedJoinColumn column = new AnnotatedJoinColumn();
column.setImplicit( true ); column.setImplicit( true );
column.setNullable( false ); //I break the spec, but it's for good column.setNullable( false ); //I break the spec, but it's for good
@ -417,7 +418,7 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
static AnnotatedJoinColumn buildExplicitJoinTableJoinColumn( static AnnotatedJoinColumn buildExplicitJoinTableJoinColumn(
AnnotatedJoinColumns parent, AnnotatedJoinColumns parent,
PropertyHolder propertyHolder, PropertyHolder propertyHolder,
String propertyName, PropertyData inferredData,
JoinColumn joinColumn) { JoinColumn joinColumn) {
final AnnotatedJoinColumn column = new AnnotatedJoinColumn(); final AnnotatedJoinColumn column = new AnnotatedJoinColumn();
column.setImplicit( true ); column.setImplicit( true );
@ -428,7 +429,7 @@ public class AnnotatedJoinColumn extends AnnotatedColumn {
column.setNullable( false ); //I break the spec, but it's for good column.setNullable( false ); //I break the spec, but it's for good
//done after the annotation to override it //done after the annotation to override it
column.setParent( parent ); column.setParent( parent );
column.applyJoinAnnotation( joinColumn, propertyName ); column.applyJoinAnnotation( joinColumn, inferredData.getPropertyName() );
column.bind(); column.bind();
return column; return column;
} }

View File

@ -67,13 +67,13 @@ public class AnnotatedJoinColumns extends AnnotatedColumns {
String mappedBy, String mappedBy,
Map<String, Join> joins, Map<String, Join> joins,
PropertyHolder propertyHolder, PropertyHolder propertyHolder,
String propertyName, PropertyData inferredData,
MetadataBuildingContext context) { MetadataBuildingContext context) {
final AnnotatedJoinColumns parent = new AnnotatedJoinColumns(); final AnnotatedJoinColumns parent = new AnnotatedJoinColumns();
parent.setBuildingContext( context ); parent.setBuildingContext( context );
parent.setJoins( joins ); parent.setJoins( joins );
parent.setPropertyHolder( propertyHolder ); parent.setPropertyHolder( propertyHolder );
parent.setPropertyName( getRelativePath( propertyHolder, propertyName ) ); parent.setPropertyName( getRelativePath( propertyHolder, inferredData.getPropertyName() ) );
parent.setMappedBy( mappedBy ); parent.setMappedBy( mappedBy );
for ( JoinColumnOrFormula columnOrFormula : joinColumnOrFormulas ) { for ( JoinColumnOrFormula columnOrFormula : joinColumnOrFormulas ) {
final JoinFormula formula = columnOrFormula.formula(); final JoinFormula formula = columnOrFormula.formula();
@ -82,23 +82,23 @@ public class AnnotatedJoinColumns extends AnnotatedColumns {
AnnotatedJoinColumn.buildJoinFormula( formula, parent ); AnnotatedJoinColumn.buildJoinFormula( formula, parent );
} }
else { else {
AnnotatedJoinColumn.buildJoinColumn( column, mappedBy, parent, propertyHolder, propertyName ); AnnotatedJoinColumn.buildJoinColumn( column, mappedBy, parent, propertyHolder, inferredData );
} }
} }
return parent; return parent;
} }
static AnnotatedJoinColumns buildJoinColumnsWithFormula( static AnnotatedJoinColumns buildJoinColumnsWithFormula(
String propertyName,
JoinFormula joinFormula, JoinFormula joinFormula,
Map<String, Join> secondaryTables, Map<String, Join> secondaryTables,
PropertyHolder propertyHolder, PropertyHolder propertyHolder,
PropertyData inferredData,
MetadataBuildingContext context) { MetadataBuildingContext context) {
final AnnotatedJoinColumns joinColumns = new AnnotatedJoinColumns(); final AnnotatedJoinColumns joinColumns = new AnnotatedJoinColumns();
joinColumns.setBuildingContext( context ); joinColumns.setBuildingContext( context );
joinColumns.setJoins( secondaryTables ); joinColumns.setJoins( secondaryTables );
joinColumns.setPropertyHolder( propertyHolder ); joinColumns.setPropertyHolder( propertyHolder );
joinColumns.setPropertyName( getRelativePath( propertyHolder, propertyName ) ); joinColumns.setPropertyName( getRelativePath( propertyHolder, inferredData.getPropertyName() ) );
AnnotatedJoinColumn.buildJoinFormula( joinFormula, joinColumns ); AnnotatedJoinColumn.buildJoinFormula( joinFormula, joinColumns );
return joinColumns; return joinColumns;
} }
@ -109,7 +109,7 @@ public class AnnotatedJoinColumns extends AnnotatedColumns {
String mappedBy, String mappedBy,
Map<String, Join> joins, Map<String, Join> joins,
PropertyHolder propertyHolder, PropertyHolder propertyHolder,
String propertyName, PropertyData inferredData,
MetadataBuildingContext buildingContext) { MetadataBuildingContext buildingContext) {
return buildJoinColumnsWithDefaultColumnSuffix( return buildJoinColumnsWithDefaultColumnSuffix(
joinColumns, joinColumns,
@ -117,7 +117,7 @@ public class AnnotatedJoinColumns extends AnnotatedColumns {
mappedBy, mappedBy,
joins, joins,
propertyHolder, propertyHolder,
propertyName, inferredData,
"", "",
buildingContext buildingContext
); );
@ -129,9 +129,10 @@ public class AnnotatedJoinColumns extends AnnotatedColumns {
String mappedBy, String mappedBy,
Map<String, Join> joins, Map<String, Join> joins,
PropertyHolder propertyHolder, PropertyHolder propertyHolder,
String propertyName, PropertyData inferredData,
String defaultColumnSuffix, String defaultColumnSuffix,
MetadataBuildingContext context) { MetadataBuildingContext context) {
final String propertyName = inferredData.getPropertyName();
final String path = qualify( propertyHolder.getPath(), propertyName ); final String path = qualify( propertyHolder.getPath(), propertyName );
final JoinColumn[] overriddes = propertyHolder.getOverriddenJoinColumn( path ); final JoinColumn[] overriddes = propertyHolder.getOverriddenJoinColumn( path );
final JoinColumn[] actualColumns = overriddes == null ? joinColumns : overriddes; final JoinColumn[] actualColumns = overriddes == null ? joinColumns : overriddes;
@ -148,7 +149,7 @@ public class AnnotatedJoinColumns extends AnnotatedColumns {
mappedBy, mappedBy,
parent, parent,
propertyHolder, propertyHolder,
propertyName, inferredData,
defaultColumnSuffix defaultColumnSuffix
); );
} }
@ -161,7 +162,7 @@ public class AnnotatedJoinColumns extends AnnotatedColumns {
mappedBy, mappedBy,
parent, parent,
propertyHolder, propertyHolder,
propertyName, inferredData,
defaultColumnSuffix defaultColumnSuffix
); );
} }
@ -173,21 +174,21 @@ public class AnnotatedJoinColumns extends AnnotatedColumns {
JoinColumn[] joinColumns, JoinColumn[] joinColumns,
Map<String, Join> secondaryTables, Map<String, Join> secondaryTables,
PropertyHolder propertyHolder, PropertyHolder propertyHolder,
String propertyName, PropertyData inferredData,
String mappedBy, String mappedBy,
MetadataBuildingContext context) { MetadataBuildingContext context) {
final AnnotatedJoinColumns parent = new AnnotatedJoinColumns(); final AnnotatedJoinColumns parent = new AnnotatedJoinColumns();
parent.setBuildingContext( context ); parent.setBuildingContext( context );
parent.setJoins( secondaryTables ); parent.setJoins( secondaryTables );
parent.setPropertyHolder( propertyHolder ); parent.setPropertyHolder( propertyHolder );
parent.setPropertyName( getRelativePath( propertyHolder, propertyName ) ); parent.setPropertyName( getRelativePath( propertyHolder, inferredData.getPropertyName() ) );
parent.setMappedBy( mappedBy ); parent.setMappedBy( mappedBy );
if ( joinColumns == null ) { if ( joinColumns == null ) {
AnnotatedJoinColumn.buildImplicitJoinTableJoinColumn( parent, propertyHolder, propertyName ); AnnotatedJoinColumn.buildImplicitJoinTableJoinColumn( parent, propertyHolder, inferredData );
} }
else { else {
for ( JoinColumn joinColumn : joinColumns ) { for ( JoinColumn joinColumn : joinColumns ) {
AnnotatedJoinColumn.buildExplicitJoinTableJoinColumn( parent, propertyHolder, propertyName, joinColumn ); AnnotatedJoinColumn.buildExplicitJoinTableJoinColumn( parent, propertyHolder, inferredData, joinColumn );
} }
} }
return parent; return parent;

View File

@ -136,7 +136,7 @@ class ColumnsBuilder {
oneToMany != null ? oneToMany.mappedBy() : "", oneToMany != null ? oneToMany.mappedBy() : "",
entityBinder.getSecondaryTables(), entityBinder.getSecondaryTables(),
propertyHolder, propertyHolder,
inferredData.getPropertyName(), inferredData,
buildingContext buildingContext
); );
} }
@ -182,7 +182,7 @@ class ColumnsBuilder {
null, null,
entityBinder.getSecondaryTables(), entityBinder.getSecondaryTables(),
propertyHolder, propertyHolder,
inferredData.getPropertyName(), inferredData,
buildingContext buildingContext
); );
} }
@ -194,7 +194,7 @@ class ColumnsBuilder {
oneToOneAnn != null ? oneToOneAnn.mappedBy() : null, oneToOneAnn != null ? oneToOneAnn.mappedBy() : null,
entityBinder.getSecondaryTables(), entityBinder.getSecondaryTables(),
propertyHolder, propertyHolder,
inferredData.getPropertyName(), inferredData,
buildingContext buildingContext
); );
} }
@ -202,8 +202,6 @@ class ColumnsBuilder {
private AnnotatedJoinColumns buildExplicitJoinColumns(XProperty property, PropertyData inferredData) { private AnnotatedJoinColumns buildExplicitJoinColumns(XProperty property, PropertyData inferredData) {
// process @JoinColumns before @Columns to handle collection of entities properly // process @JoinColumns before @Columns to handle collection of entities properly
final String propertyName = inferredData.getPropertyName();
final JoinColumn[] joinColumnAnnotations = getJoinColumnAnnotations( property, inferredData ); final JoinColumn[] joinColumnAnnotations = getJoinColumnAnnotations( property, inferredData );
if ( joinColumnAnnotations != null ) { if ( joinColumnAnnotations != null ) {
return AnnotatedJoinColumns.buildJoinColumns( return AnnotatedJoinColumns.buildJoinColumns(
@ -212,7 +210,7 @@ class ColumnsBuilder {
null, null,
entityBinder.getSecondaryTables(), entityBinder.getSecondaryTables(),
propertyHolder, propertyHolder,
propertyName, inferredData,
buildingContext buildingContext
); );
} }
@ -224,7 +222,7 @@ class ColumnsBuilder {
null, null,
entityBinder.getSecondaryTables(), entityBinder.getSecondaryTables(),
propertyHolder, propertyHolder,
propertyName, inferredData,
buildingContext buildingContext
); );
} }
@ -232,10 +230,10 @@ class ColumnsBuilder {
if ( property.isAnnotationPresent( JoinFormula.class) ) { if ( property.isAnnotationPresent( JoinFormula.class) ) {
final JoinFormula joinFormula = getOverridableAnnotation( property, JoinFormula.class, buildingContext ); final JoinFormula joinFormula = getOverridableAnnotation( property, JoinFormula.class, buildingContext );
return AnnotatedJoinColumns.buildJoinColumnsWithFormula( return AnnotatedJoinColumns.buildJoinColumnsWithFormula(
propertyName,
joinFormula, joinFormula,
entityBinder.getSecondaryTables(), entityBinder.getSecondaryTables(),
propertyHolder, propertyHolder,
inferredData,
buildingContext buildingContext
); );
} }

View File

@ -63,7 +63,7 @@ public class ToOneFkSecondPass extends FkSecondPass {
} }
final PersistentClass persistentClass = buildingContext.getMetadataCollector() final PersistentClass persistentClass = buildingContext.getMetadataCollector()
.getEntityBinding( entityClassName ); .getEntityBinding( entityClassName );
Property property = persistentClass.getIdentifierProperty(); final Property property = persistentClass.getIdentifierProperty();
if ( path == null ) { if ( path == null ) {
return false; return false;
} }
@ -82,7 +82,7 @@ public class ToOneFkSecondPass extends FkSecondPass {
localPath = path.substring( 3 ); localPath = path.substring( 3 );
} }
Component component = (Component) valueIdentifier; final Component component = (Component) valueIdentifier;
for ( Property idProperty : component.getProperties() ) { for ( Property idProperty : component.getProperties() ) {
if ( localPath.equals( idProperty.getName() ) || localPath.startsWith( idProperty.getName() + "." ) ) { if ( localPath.equals( idProperty.getName() ) || localPath.startsWith( idProperty.getName() + "." ) ) {
return true; return true;

View File

@ -388,7 +388,7 @@ public abstract class CollectionBinder {
null, null,
entityBinder.getSecondaryTables(), entityBinder.getSecondaryTables(),
propertyHolder, propertyHolder,
inferredData.getPropertyName(), inferredData,
"_KEY", "_KEY",
context context
); );
@ -706,7 +706,7 @@ public abstract class CollectionBinder {
annJoins, annJoins,
entityBinder.getSecondaryTables(), entityBinder.getSecondaryTables(),
propertyHolder, propertyHolder,
inferredData.getPropertyName(), inferredData,
mappedBy, mappedBy,
buildingContext buildingContext
) ); ) );
@ -714,7 +714,7 @@ public abstract class CollectionBinder {
annInverseJoins, annInverseJoins,
entityBinder.getSecondaryTables(), entityBinder.getSecondaryTables(),
propertyHolder, propertyHolder,
inferredData.getPropertyName(), inferredData,
mappedBy, mappedBy,
buildingContext buildingContext
) ); ) );

View File

@ -0,0 +1,137 @@
package org.hibernate.orm.test.ondelete.toone;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.ManyToOne;
import org.hibernate.annotations.ColumnDefault;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
import org.hibernate.dialect.SybaseDialect;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.hibernate.testing.orm.junit.SkipForDialect;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
@DomainModel(
annotatedClasses = {
ToOneOnDeleteSetNullTest.Parent.class,
ToOneOnDeleteSetNullTest.Child.class,
ToOneOnDeleteSetNullTest.GrandChild.class
}
)
@SessionFactory
public class ToOneOnDeleteSetNullTest {
@AfterEach
public void tearDown(SessionFactoryScope scope) {
scope.getSessionFactory().getSchemaManager().truncateMappedObjects();
}
@Test
@SkipForDialect(
dialectClass = SybaseDialect.class,
matchSubTypes = true,
reason = "Sybase does not support on delete actions"
)
public void testManyToOne(SessionFactoryScope scope) {
scope.inTransaction(
session -> {
Parent parent = new Parent();
parent.id = 1L;
session.persist( parent );
Child child1 = new Child();
child1.id = 1L;
child1.parent = parent;
session.persist( child1 );
GrandChild grandChild11 = new GrandChild();
grandChild11.id = 1L;
grandChild11.parent = child1;
session.persist( grandChild11 );
Child child2 = new Child();
child2.id = 2L;
child2.parent = parent;
session.persist( child2 );
GrandChild grandChild21 = new GrandChild();
grandChild21.id = 2L;
grandChild21.parent = child2;
session.persist( grandChild21 );
GrandChild grandChild22 = new GrandChild();
grandChild22.id = 3L;
grandChild22.parent = child2;
session.persist( grandChild22 );
}
);
scope.inTransaction(
session -> {
assertNotNull( session.get(Child.class, 1L).parent );
assertNotNull( session.get(Child.class, 2L).parent );
assertNotNull( session.get(GrandChild.class, 2L).parent );
assertNotNull( session.get(GrandChild.class, 3L).parent );
}
);
scope.inTransaction(
session -> {
Parent parent = session.get( Parent.class, 1L );
session.remove( parent );
}
);
scope.inTransaction(
session -> {
assertNull( session.get(Child.class, 1L).parent );
assertNull( session.get(Child.class, 2L).parent );
assertNotNull( session.get(GrandChild.class, 2L).parent );
assertNotNull( session.get(GrandChild.class, 3L).parent );
assertNull( session.get( Parent.class, 1L ) );
}
);
}
@Entity(name = "Parent")
public static class Parent {
@Id
private Long id;
private String name;
}
@Entity(name = "Child")
public static class Child {
@Id
private Long id;
private String name;
@ManyToOne
@OnDelete(action = OnDeleteAction.SET_NULL)
private Parent parent;
}
@Entity(name = "GrandChild")
public static class GrandChild {
@Id
private Long id;
private String name;
@ManyToOne
@OnDelete(action = OnDeleteAction.SET_DEFAULT)
@ColumnDefault("null")
private Child parent;
}
}

View File

@ -3,7 +3,6 @@ package org.hibernate.orm.test.ondelete.toone;
import jakarta.persistence.Entity; import jakarta.persistence.Entity;
import jakarta.persistence.Id; import jakarta.persistence.Id;
import jakarta.persistence.ManyToOne; import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToOne;
import org.hibernate.annotations.OnDelete; import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction; import org.hibernate.annotations.OnDeleteAction;
@ -16,6 +15,9 @@ import org.hibernate.testing.orm.junit.SkipForDialect;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
/** /**
* @author Vlad Mihalcea * @author Vlad Mihalcea
@ -31,21 +33,15 @@ import org.junit.jupiter.api.Test;
public class ToOneOnDeleteTest { public class ToOneOnDeleteTest {
@AfterEach @AfterEach
public void tearDown(SessionFactoryScope scope){ public void tearDown(SessionFactoryScope scope) {
scope.inTransaction( scope.getSessionFactory().getSchemaManager().truncateMappedObjects();
session -> {
session.createQuery( "delete from Parent" ).executeUpdate();
session.createQuery( "delete from Child" ).executeUpdate();
session.createQuery( "delete from GrandChild" ).executeUpdate();
}
);
} }
@Test @Test
@SkipForDialect( @SkipForDialect(
dialectClass = SybaseDialect.class, dialectClass = SybaseDialect.class,
matchSubTypes = true, matchSubTypes = true,
reason = "HHH-13559 on-delete=\"cascade\" is not supported for unidirectional to-one associations using Sybase" reason = "Sybase does not support on delete actions"
) )
public void testManyToOne(SessionFactoryScope scope) { public void testManyToOne(SessionFactoryScope scope) {
scope.inTransaction( scope.inTransaction(
@ -83,11 +79,27 @@ public class ToOneOnDeleteTest {
scope.inTransaction( scope.inTransaction(
session -> { session -> {
Parent parent = session.get( Parent.class, 1L ); assertNotNull( session.get(Child.class, 1L) );
session.delete( parent ); assertNotNull( session.get(Child.class, 2L) );
assertNotNull( session.get(GrandChild.class, 2L) );
assertNotNull( session.get(GrandChild.class, 3L) );
} }
); );
scope.inTransaction(
session -> {
Parent parent = session.get( Parent.class, 1L );
session.remove( parent );
} }
);
scope.inTransaction(
session -> {
assertNull( session.get(Child.class, 1L) );
assertNull( session.get(Child.class, 2L) );
assertNull( session.get(GrandChild.class, 2L) );
assertNull( session.get(GrandChild.class, 3L) );
assertNull( session.get( Parent.class, 1L ) );
}
); }
@Entity(name = "Parent") @Entity(name = "Parent")