HHH-17228 - apply the discriminator for 1-1 mappings to single-table-inheritance subclass attributes

Signed-off-by: Jan Schatteman <jschatte@redhat.com>
This commit is contained in:
Jan Schatteman 2023-09-20 19:17:55 +02:00 committed by Jan Schatteman
parent 8df6d39b97
commit aa7a2cc0f0
2 changed files with 116 additions and 5 deletions

View File

@ -1972,6 +1972,9 @@ public class ToOneAttributeMapping
true, true,
creationState creationState
); );
if ( getAssociatedEntityMappingType().getSuperMappingType() != null && !creationState.supportsEntityNameUsage() ) {
getAssociatedEntityMappingType().applyDiscriminator( null, null, tableGroup, creationState );
}
} }
); );

View File

@ -6,11 +6,14 @@
*/ */
package org.hibernate.orm.test.onetoone.singletable; package org.hibernate.orm.test.onetoone.singletable;
import java.util.List;
import org.hibernate.dialect.SybaseDialect; import org.hibernate.dialect.SybaseDialect;
import org.hibernate.exception.ConstraintViolationException; import org.hibernate.exception.ConstraintViolationException;
import org.hibernate.testing.orm.junit.DomainModel; import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.JiraKey; import org.hibernate.testing.orm.junit.JiraKey;
import org.hibernate.testing.orm.junit.JiraKeyGroup;
import org.hibernate.testing.orm.junit.SessionFactory; import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope; import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.hibernate.testing.orm.junit.SkipForDialect; import org.hibernate.testing.orm.junit.SkipForDialect;
@ -30,6 +33,7 @@ import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToOne; import jakarta.persistence.OneToOne;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertThrows;
/** /**
@ -41,7 +45,10 @@ import static org.junit.jupiter.api.Assertions.assertThrows;
} }
) )
@SessionFactory @SessionFactory
@JiraKey( value = "HHH-16916") @JiraKeyGroup( value = {
@JiraKey( value = "HHH-16916"),
@JiraKey( value = "HHH-17228")
} )
public class SingleTableOneToOneTest { public class SingleTableOneToOneTest {
@AfterEach @AfterEach
@ -84,19 +91,101 @@ public class SingleTableOneToOneTest {
@Test @Test
public void testMultipleRelationshipsOnSingleTableInheritanceCorrectlyMappedAsManyToOne(SessionFactoryScope scope) { public void testMultipleRelationshipsOnSingleTableInheritanceCorrectlyMappedAsManyToOne(SessionFactoryScope scope) {
scope.inTransaction(
session -> {
SubClass1 subClass121 = new SubClass1();
subClass121.setId(121L);
SubClass2 subClass221 = new SubClass2();
subClass221.setId(221L);
Container2 container21 = new Container2();
container21.setId( 21L );
container21.setSubClass12( subClass121 );
container21.setSubClass22( subClass221 );
subClass121.setManyToOneContainer( container21 );
subClass221.setManyToOneContainer( container21 );
session.persist( container21 );
SubClass2 subClass222 = new SubClass2();
subClass222.setId(222L);
Container2 container22 = new Container2();
container22.setId( 22L );
container22.setSubClass22( subClass222 );
subClass222.setManyToOneContainer( container22 );
session.persist( container22 );
}
);
scope.inTransaction(
session -> {
List<SubClass1> result1 = session.createSelectionQuery( "from SubClass1", SubClass1.class ).getResultList();
assertEquals( 1, result1.size() );
assertEquals( 121L, result1.get(0).getId() );
List<SubClass2> result2 = session.createSelectionQuery( "from SubClass2 sc order by sc.id", SubClass2.class ).getResultList();
assertEquals( 2, result2.size() );
assertEquals( 221L, result2.get(0).getId() );
assertEquals( 222L, result2.get(1).getId() );
List<Container2> result3 = session.createSelectionQuery( "from Container2 c order by c.id", Container2.class ).getResultList();
assertEquals( 2, result3.size() );
assertEquals( 21L, result3.get(0).getId() );
assertEquals( 22L, result3.get(1).getId() );
SubClass1 sc1 = session.find( SubClass1.class, 121L );
assertEquals( 21L, sc1.getManyToOneContainer().getId() );
SubClass2 sc2 = session.find( SubClass2.class, 222L );
assertEquals( 22L, sc2.getManyToOneContainer().getId() );
Container2 c2 = session.find( Container2.class, 21L );
assertEquals( 121L, c2.getSubClass12().getId() );
assertEquals( 221L, c2.getSubClass22().getId() );
c2 = session.find( Container2.class, 22L );
assertEquals( 222L, c2.getSubClass22().getId() );
assertNull( c2.getSubClass12() );
}
);
tearDown( scope );
scope.inTransaction( scope.inTransaction(
session -> { session -> {
SubClass1 subClass12 = new SubClass1(); SubClass1 subClass12 = new SubClass1();
subClass12.setId(12L); subClass12.setId(12L);
Container2 container = new Container2();
container.setId( 2L );
container.setSubClass12( subClass12 );
subClass12.setManyToOneContainer( container );
session.persist( container );
}
);
scope.inTransaction(
session -> {
List<SubClass1> result1 = session.createSelectionQuery( "from SubClass1", SubClass1.class ).getResultList();
assertEquals( 1, result1.size() );
assertEquals( 12L, result1.get(0).getId() );
List<SubClass2> result2 = session.createSelectionQuery( "from SubClass2", SubClass2.class ).getResultList();
assertEquals( 0, result2.size() );
}
);
tearDown( scope );
scope.inTransaction(
session -> {
SubClass2 subClass22 = new SubClass2(); SubClass2 subClass22 = new SubClass2();
subClass22.setId(22L); subClass22.setId(22L);
Container2 container = new Container2(); Container2 container = new Container2();
container.setId( 2L ); container.setId( 2L );
container.setSubClass12( subClass12 );
container.setSubClass22( subClass22 ); container.setSubClass22( subClass22 );
subClass12.setManyToOneContainer( container );
subClass22.setManyToOneContainer( container ); subClass22.setManyToOneContainer( container );
session.persist( container ); session.persist( container );
@ -104,8 +193,11 @@ public class SingleTableOneToOneTest {
); );
scope.inTransaction( scope.inTransaction(
session -> { session -> {
assertEquals( 1L, session.createSelectionQuery( "select count(*) from SubClass1", Long.class ).getSingleResult() ); List<SubClass1> result1 = session.createSelectionQuery( "from SubClass1", SubClass1.class ).getResultList();
assertEquals( 1L, session.createSelectionQuery( "select count(*) from SubClass2", Long.class ).getSingleResult() ); assertEquals( 0, result1.size() );
List<SubClass2> result2 = session.createSelectionQuery( "from SubClass2", SubClass2.class ).getResultList();
assertEquals( 1, result2.size() );
assertEquals( 22L, result2.get(0).getId() );
} }
); );
@ -138,6 +230,10 @@ public class SingleTableOneToOneTest {
this.oneToOneContainer = oneToOneContainer; this.oneToOneContainer = oneToOneContainer;
} }
public Container2 getManyToOneContainer() {
return manyToOneContainer;
}
public void setManyToOneContainer(Container2 manyToOneContainer) { public void setManyToOneContainer(Container2 manyToOneContainer) {
this.manyToOneContainer = manyToOneContainer; this.manyToOneContainer = manyToOneContainer;
} }
@ -188,10 +284,22 @@ public class SingleTableOneToOneTest {
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "manyToOneContainer", orphanRemoval = true) @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "manyToOneContainer", orphanRemoval = true)
private SubClass2 subClass22; private SubClass2 subClass22;
public Long getId() {
return id;
}
public void setId(Long id) { public void setId(Long id) {
this.id = id; this.id = id;
} }
public SubClass1 getSubClass12() {
return subClass12;
}
public SubClass2 getSubClass22() {
return subClass22;
}
public void setSubClass12(SubClass1 subClass12) { public void setSubClass12(SubClass1 subClass12) {
this.subClass12 = subClass12; this.subClass12 = subClass12;
} }