diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/orphan/onetomany/embedded/OneToManyInEmbeddedTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/orphan/onetomany/embedded/OneToManyInEmbeddedTest.java index 042b616348..1f72da6862 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/orphan/onetomany/embedded/OneToManyInEmbeddedTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/jpa/orphan/onetomany/embedded/OneToManyInEmbeddedTest.java @@ -6,19 +6,21 @@ */ package org.hibernate.orm.test.jpa.orphan.onetomany.embedded; +import java.util.ArrayList; import java.util.List; import org.hibernate.testing.orm.junit.EntityManagerFactoryScope; -import org.hibernate.testing.orm.junit.JiraKey; +import org.hibernate.testing.orm.junit.Jira; import org.hibernate.testing.orm.junit.Jpa; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import jakarta.persistence.CascadeType; import jakarta.persistence.Embeddable; import jakarta.persistence.Embedded; import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; import jakarta.persistence.JoinColumn; @@ -29,21 +31,20 @@ import static org.junit.jupiter.api.Assertions.assertTrue; /** * @author Marco Belladelli */ -@Jpa(annotatedClasses = { +@Jpa( annotatedClasses = { OneToManyInEmbeddedTest.ChildEntity.class, OneToManyInEmbeddedTest.ParentEntity.class -}) -@JiraKey("HHH-15864") +} ) public class OneToManyInEmbeddedTest { - @BeforeEach + @BeforeAll public void setUp(EntityManagerFactoryScope scope) { scope.inTransaction( entityManager -> { - ParentEntity parentEntity = new ParentEntity( new ChildEntityWrapper( List.of( new ChildEntity() ) ) ); - entityManager.persist( parentEntity ); + entityManager.persist( new ParentEntity( ChildWrapper.of( new ChildEntity( 1 ) ), null ) ); + entityManager.persist( new ParentEntity( null, EagerChildWrapper.of( new ChildEntity( 2 ) ) ) ); } ); } - @AfterEach + @AfterAll public void tearDown(EntityManagerFactoryScope scope) { scope.inTransaction( entityManager -> { entityManager.createQuery( "delete from ChildEntity" ).executeUpdate(); @@ -52,86 +53,114 @@ public class OneToManyInEmbeddedTest { } @Test + @Jira( "https://hibernate.atlassian.net/browse/HHH-15864" ) public void testOrphanRemovalInEmbedded(EntityManagerFactoryScope scope) { scope.inTransaction( entityManager -> { - ParentEntity parentEntity = entityManager.find( ParentEntity.class, 1 ); - parentEntity.getChildEntityWrapper().getChildEntities().clear(); + final ParentEntity parentEntity = entityManager.find( ParentEntity.class, 1 ); + parentEntity.getChildWrapper().getChildEntities().clear(); entityManager.remove( parentEntity ); } ); - scope.inTransaction( entityManager -> assertTrue( - entityManager.createQuery( "from ChildEntity" ).getResultList().isEmpty(), + entityManager.createQuery( "from ChildEntity where id = 1" ).getResultList().isEmpty(), "Orphan entity was not removed" ) ); } - @Entity(name = "ChildEntity") + @Test + @Jira( "https://hibernate.atlassian.net/browse/HHH-16970" ) + public void testOrphanRemovalInEmbeddedEager(EntityManagerFactoryScope scope) { + scope.inTransaction( entityManager -> { + final ParentEntity parentEntity = entityManager.find( ParentEntity.class, 2 ); + parentEntity.getEagerChildWrapper().getChildEntities().clear(); + entityManager.remove( parentEntity ); + } ); + scope.inTransaction( entityManager -> assertTrue( + entityManager.createQuery( "from ChildEntity where id = 2" ).getResultList().isEmpty(), + "Orphan entity was not removed" + ) ); + } + + @Entity( name = "ChildEntity" ) public static class ChildEntity { @Id - @GeneratedValue private int id; public int getId() { return id; } - public void setId(int id) { + public ChildEntity() { + } + + public ChildEntity(int id) { this.id = id; } } @Embeddable - public static class ChildEntityWrapper { - @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true) - @JoinColumn(name = "parent_entity_id", referencedColumnName = "id") - private List childEntities; + public static class ChildWrapper { + @OneToMany( cascade = CascadeType.ALL, orphanRemoval = true ) + @JoinColumn( name = "parent_entity_id", referencedColumnName = "id" ) + private List childEntities = new ArrayList<>(); - public ChildEntityWrapper() { - } - - public ChildEntityWrapper(List childEntities) { - this.childEntities = childEntities; + public static ChildWrapper of(ChildEntity... childEntities) { + final ChildWrapper cw = new ChildWrapper(); + cw.getChildEntities().addAll( List.of( childEntities ) ); + return cw; } public List getChildEntities() { return childEntities; } + } - public void setChildEntities(List childEntities) { - this.childEntities = childEntities; + @Embeddable + public static class EagerChildWrapper { + @OneToMany( fetch = FetchType.EAGER, cascade = CascadeType.ALL, orphanRemoval = true ) + @JoinColumn( name = "parent_entity_id", referencedColumnName = "id" ) + private List childEntities = new ArrayList<>(); + + public static EagerChildWrapper of(ChildEntity... childEntities) { + final EagerChildWrapper cw = new EagerChildWrapper(); + cw.getChildEntities().addAll( List.of( childEntities ) ); + return cw; + } + + public List getChildEntities() { + return childEntities; } } - @Entity(name = "ParentEntity") + @Entity( name = "ParentEntity" ) public static class ParentEntity { @Id @GeneratedValue private int id; @Embedded - private ChildEntityWrapper childEntityWrapper = new ChildEntityWrapper(); + private ChildWrapper childWrapper; + + @Embedded + private EagerChildWrapper eagerChildWrapper; public ParentEntity() { } - public ParentEntity(ChildEntityWrapper childEntityWrapper) { - this.childEntityWrapper = childEntityWrapper; + public ParentEntity(ChildWrapper childWrapper, EagerChildWrapper eagerChildWrapper) { + this.childWrapper = childWrapper; + this.eagerChildWrapper = eagerChildWrapper; } public int getId() { return id; } - public void setId(int id) { - this.id = id; + public ChildWrapper getChildWrapper() { + return childWrapper; } - public ChildEntityWrapper getChildEntityWrapper() { - return childEntityWrapper; - } - - public void setChildEntityWrapper(ChildEntityWrapper childEntityWrapper) { - this.childEntityWrapper = childEntityWrapper; + public EagerChildWrapper getEagerChildWrapper() { + return eagerChildWrapper; } } }