diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/id/ReSaveReferencedDeletedEntity.java b/hibernate-core/src/test/java/org/hibernate/orm/test/id/ReSaveReferencedDeletedEntity.java new file mode 100644 index 0000000000..855055d7cb --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/id/ReSaveReferencedDeletedEntity.java @@ -0,0 +1,112 @@ +/* + * SPDX-License-Identifier: LGPL-2.1-or-later + * Copyright Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.orm.test.id; + +import org.hibernate.cfg.AvailableSettings; +import org.hibernate.cfg.Configuration; +import org.hibernate.testing.orm.junit.JiraKey; +import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; +import org.junit.Test; + +import jakarta.persistence.*; + +import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate; + +public class ReSaveReferencedDeletedEntity extends BaseCoreFunctionalTestCase { + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { Child.class, Parent.class }; + } + + @Override + protected void configure(Configuration configuration) { + super.configure( configuration ); + configuration.setProperty( AvailableSettings.USE_IDENTIFIER_ROLLBACK, "true" ); + } + + @Test + @JiraKey("HHH-14416") + public void testReSaveDeletedEntity() { + doInHibernate( this::sessionFactory, session -> { + Parent parent = new Parent(); + + Child child = new Child(); + parent.setChild( child ); + + session.persist( parent ); + + parent.setChild( null ); + session.remove(child); + + session.flush(); + + parent.setChild( child ); + session.persist(child); + } ); + } + + @Test + @JiraKey("HHH-14416") + public void testReSaveDeletedEntityWithDetach() { + doInHibernate( this::sessionFactory, session -> { + Parent parent = new Parent(); + + Child child = new Child(); + parent.setChild( child ); + + session.persist( parent ); + + parent.setChild( null ); + session.remove(child); + + session.flush(); + session.detach(child); + + parent.setChild( child ); + session.persist(child); + } ); + } + + @Entity(name = "Child") + public static class Child { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + } + + @Entity(name = "Parent") + public static class Parent { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + @OneToOne(cascade = CascadeType.ALL) + private Child child; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public Child getChild() { + return child; + } + + public void setChild(Child child) { + this.child = child; + } + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/id/ReSaveReferencedDeletedEntityJPA.java b/hibernate-core/src/test/java/org/hibernate/orm/test/id/ReSaveReferencedDeletedEntityJPA.java new file mode 100644 index 0000000000..5de83db03f --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/id/ReSaveReferencedDeletedEntityJPA.java @@ -0,0 +1,122 @@ +/* + * SPDX-License-Identifier: LGPL-2.1-or-later + * Copyright Red Hat Inc. and Hibernate Authors + */ +package org.hibernate.orm.test.id; + +import org.hibernate.cfg.AvailableSettings; +import org.hibernate.testing.orm.junit.JiraKey; +import org.hibernate.orm.test.jpa.BaseEntityManagerFunctionalTestCase; +import org.junit.Test; + +import jakarta.persistence.*; + +import java.util.Map; + +public class ReSaveReferencedDeletedEntityJPA extends BaseEntityManagerFunctionalTestCase { + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { Child.class, Parent.class }; + } + + @Override + protected Map buildSettings() { + Map settings = super.buildSettings(); + settings.put( AvailableSettings.USE_IDENTIFIER_ROLLBACK, "true" ); + return settings; + } + + @Test + @ JiraKey("HHH-14416") + public void testRefreshUnDeletedEntityWithReferencesJPA() { + EntityManager em = getOrCreateEntityManager(); + em.getTransaction().begin(); + + Parent parent = new Parent(); + parent.setId(1); + + Child child = new Child(); + child.setId(2); + parent.setChild( child ); + + em.persist( parent ); + + em.flush(); + + em.remove( parent ); + + em.flush(); + + em.detach( parent ); + + em.persist( parent ); + + em.flush(); + + em.refresh( child ); + + em.getTransaction().commit(); + } + + @Test + @JiraKey("HHH-14416") + public void testReSaveDeletedEntityWithReferencesJPA() { + EntityManager em = getOrCreateEntityManager(); + em.getTransaction().begin(); + + Parent parent = new Parent(); + parent.setId(1); + + Child child = new Child(); + child.setId(2); + parent.setChild( child ); + + em.persist( parent ); + + parent.setChild( null ); + em.remove( child ); + + em.persist( child ); + + em.getTransaction().commit(); + } + + @Entity(name = "Child") + public static class Child { + @Id + private Integer id; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + } + + @Entity(name = "Parent") + public static class Parent { + @Id + private Integer id; + + @OneToOne(cascade = CascadeType.ALL) + private Child child; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public Child getChild() { + return child; + } + + public void setChild(Child child) { + this.child = child; + } + } +}