From 333c190c826e1ad4058b85b6d98b8566b6c5fc36 Mon Sep 17 00:00:00 2001 From: Chris Cranford Date: Mon, 23 Jul 2018 10:33:51 -0400 Subject: [PATCH] HHH-12846 - Merge cascade of collection fails when orphan removal enabled with flush mode commit. --- .../internal/DefaultLoadEventListener.java | 6 ++- .../flush/CommitFlushCollectionTest.java | 49 +++++++++++++++++-- 2 files changed, 48 insertions(+), 7 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultLoadEventListener.java b/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultLoadEventListener.java index 855e5e8a54..e160b24e31 100644 --- a/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultLoadEventListener.java +++ b/hibernate-core/src/main/java/org/hibernate/event/internal/DefaultLoadEventListener.java @@ -14,6 +14,7 @@ import org.hibernate.NonUniqueObjectException; import org.hibernate.PersistentObjectException; import org.hibernate.TypeMismatchException; import org.hibernate.WrongClassException; +import org.hibernate.action.internal.DelayedPostInsertIdentifier; import org.hibernate.cache.spi.access.EntityDataAccess; import org.hibernate.cache.spi.access.SoftLock; import org.hibernate.cache.spi.entry.CacheEntry; @@ -30,7 +31,6 @@ import org.hibernate.engine.spi.PersistenceContext; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.engine.spi.Status; -import org.hibernate.event.service.spi.EventListenerGroup; import org.hibernate.event.service.spi.EventListenerRegistry; import org.hibernate.event.spi.EventSource; import org.hibernate.event.spi.EventType; @@ -83,7 +83,9 @@ public class DefaultLoadEventListener extends AbstractLockUpgradeEventListener i } final Class idClass = persister.getIdentifierType().getReturnedClass(); - if ( idClass != null && !idClass.isInstance( event.getEntityId() ) ) { + if ( idClass != null && + !idClass.isInstance( event.getEntityId() ) && + !DelayedPostInsertIdentifier.class.isInstance( event.getEntityId() ) ) { checkIdClass( persister, event, loadType, idClass ); } diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/flush/CommitFlushCollectionTest.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/flush/CommitFlushCollectionTest.java index 2baf8ce656..ccce6841d9 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/flush/CommitFlushCollectionTest.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/flush/CommitFlushCollectionTest.java @@ -39,7 +39,7 @@ import static org.junit.Assert.assertEquals; /** * @author Chris Cranford */ -@TestForIssue(jiraKey = "HHH-12826") +@TestForIssue(jiraKey = "HHH-12826 and HHH-12846") public class CommitFlushCollectionTest extends BaseEnversJPAFunctionalTestCase { @MappedSuperclass @@ -184,6 +184,38 @@ public class CommitFlushCollectionTest extends BaseEnversJPAFunctionalTestCase { } } + private void mergeDocument(FlushModeType flushModeType, Long id) { + final EntityManager entityManager = getOrCreateEntityManager(); + try { + entityManager.setFlushMode( flushModeType ); + + entityManager.getTransaction().begin(); + DocumentA doc = entityManager.find( DocumentA.class, id ); + doc.setDate( new Date() ); + for ( DocumentLineA line : doc.getLines() ) { + line.setText( "Updated" ); + } + + DocumentLineA line = new DocumentLineA(); + line.setText( "line2" ); + doc.addLine( line ); + + entityManager.merge( doc ); + entityManager.getTransaction().commit(); + } + catch ( Exception e ) { + if ( entityManager != null && entityManager.getTransaction().isActive() ) { + entityManager.getTransaction().rollback(); + } + throw e; + } + finally { + if ( entityManager != null && entityManager.isOpen() ) { + entityManager.close(); + } + } + } + private Long entityId1; private Long entityId2; @@ -192,18 +224,25 @@ public class CommitFlushCollectionTest extends BaseEnversJPAFunctionalTestCase { public void initData() { // This failed when using Envers. entityId1 = persistDocument( FlushModeType.COMMIT ); + // This worked entityId2 = persistDocument( FlushModeType.AUTO ); + + // This failed + mergeDocument( FlushModeType.COMMIT, entityId1 ); + + // This worked + mergeDocument( FlushModeType.AUTO, entityId2 ); } @Test - public void testPersistWithFlushModeCommit() { - assertEquals( Arrays.asList( 1 ), getAuditReader().getRevisions( DocumentA.class, entityId1 ) ); + public void testWithFlushModeCommit() { + assertEquals( Arrays.asList( 1, 3 ), getAuditReader().getRevisions( DocumentA.class, entityId1 ) ); } @Test @Priority(1) - public void testPersistWithFlushmodeAuto() { - assertEquals( Arrays.asList( 2 ), getAuditReader().getRevisions( DocumentA.class, entityId2 ) ); + public void testWithFlushModeAuto() { + assertEquals( Arrays.asList( 2, 4 ), getAuditReader().getRevisions( DocumentA.class, entityId2 ) ); } }