diff --git a/hibernate-core/src/test/java/org/hibernate/test/collection/delayedOperation/DetachedBagDelayedOperationTest.java b/hibernate-core/src/test/java/org/hibernate/test/collection/delayedOperation/DetachedBagDelayedOperationTest.java index 2e5cea84d501..e6b2fd95e2ad 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/collection/delayedOperation/DetachedBagDelayedOperationTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/collection/delayedOperation/DetachedBagDelayedOperationTest.java @@ -15,6 +15,7 @@ import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; +import javax.persistence.EntityExistsException; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @@ -41,6 +42,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; /** * Tests merge of detached PersistentBag @@ -70,6 +72,7 @@ protected Class[] getAnnotatedClasses() { private Triggerable triggerableIgnoreQueuedOperationsOnMerge; private Triggerable triggerableQueuedOperationWhenAttachToSession; private Triggerable triggerableQueuedOperationWhenDetachFromSession; + private Triggerable triggerableQueuedOperationOnRollback; @Before public void setup() { @@ -92,6 +95,7 @@ public void setup() { triggerableIgnoreQueuedOperationsOnMerge = logInspectionCollectionType.watchForLogMessages( "HHH000494" ); triggerableQueuedOperationWhenAttachToSession = logInspectionAbstractPersistentCollection.watchForLogMessages( "HHH000495" ); triggerableQueuedOperationWhenDetachFromSession = logInspectionAbstractPersistentCollection.watchForLogMessages( "HHH000496" ); + triggerableQueuedOperationOnRollback = logInspectionAbstractPersistentCollection.watchForLogMessages( "HHH000498" ); resetTriggerables(); } @@ -269,6 +273,51 @@ public void testSaveOrUpdateDetachedCollectionWithQueuedOperations() { checkTriggerablesNotTriggered(); } + @Test + @TestForIssue( jiraKey = "HHH-11209" ) + public void testCollectionWithQueuedOperationsOnRollback() { + final Parent pOriginal = doInHibernate( + this::sessionFactory, session -> { + Parent p = session.get( Parent.class, 1L ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + // initialize + Hibernate.initialize( p.getChildren() ); + assertTrue( Hibernate.isInitialized( p.getChildren() ) ); + return p; + } + ); + try { + doInHibernate( + this::sessionFactory, session -> { + Parent p = (Parent) session.merge( pOriginal ); + Child c = new Child( "Zeke" ); + c.setParent( p ); + session.persist( c ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + p.getChildren().add( c ); + assertFalse( Hibernate.isInitialized( p.getChildren() ) ); + assertTrue( ( (AbstractPersistentCollection) p.getChildren() ).hasQueuedOperations() ); + + checkTriggerablesNotTriggered(); + + // save a new Parent with the same ID to throw an exception. + + Parent pDup = new Parent(); + pDup.id = 1L; + session.persist( pDup ); + } + ); + fail( "should have thrown EntityExistsException" ); + } + catch (EntityExistsException expected) { + } + + assertTrue( triggerableQueuedOperationOnRollback.wasTriggered() ); + triggerableQueuedOperationOnRollback.reset(); + + checkTriggerablesNotTriggered(); + } + private void resetTriggerables() { triggerableIgnoreQueuedOperationsOnMerge.reset(); triggerableQueuedOperationWhenAttachToSession.reset(); diff --git a/hibernate-core/src/test/resources/log4j.properties b/hibernate-core/src/test/resources/log4j.properties index eb96581a28b5..329de4fdaeb4 100644 --- a/hibernate-core/src/test/resources/log4j.properties +++ b/hibernate-core/src/test/resources/log4j.properties @@ -58,3 +58,4 @@ log4j.logger.org.hibernate.type.descriptor.java.JavaTypeDescriptorRegistry=debug log4j.logger.org.hibernate.testing.junit4.TestClassMetadata=info, unclosedSessionFactoryFile log4j.logger.org.hibernate.boot.model.process.internal.ScanningCoordinator=debug +log4j.logger.org.hibernate.collection.internal.AbstractPersistentCollection=debug