HHH-12846 - Merge cascade of collection fails when orphan removal enabled with flush mode commit.

(cherry picked from commit 333c190c82)
This commit is contained in:
Chris Cranford 2018-07-23 10:33:51 -04:00
parent 03a209c8ec
commit 27449d2dc2
2 changed files with 48 additions and 7 deletions

View File

@ -14,6 +14,7 @@ import org.hibernate.NonUniqueObjectException;
import org.hibernate.PersistentObjectException; import org.hibernate.PersistentObjectException;
import org.hibernate.TypeMismatchException; import org.hibernate.TypeMismatchException;
import org.hibernate.WrongClassException; import org.hibernate.WrongClassException;
import org.hibernate.action.internal.DelayedPostInsertIdentifier;
import org.hibernate.cache.spi.access.EntityDataAccess; import org.hibernate.cache.spi.access.EntityDataAccess;
import org.hibernate.cache.spi.access.SoftLock; import org.hibernate.cache.spi.access.SoftLock;
import org.hibernate.cache.spi.entry.CacheEntry; 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.SessionFactoryImplementor;
import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.engine.spi.Status; import org.hibernate.engine.spi.Status;
import org.hibernate.event.service.spi.EventListenerGroup;
import org.hibernate.event.service.spi.EventListenerRegistry; import org.hibernate.event.service.spi.EventListenerRegistry;
import org.hibernate.event.spi.EventSource; import org.hibernate.event.spi.EventSource;
import org.hibernate.event.spi.EventType; import org.hibernate.event.spi.EventType;
@ -83,7 +83,9 @@ public class DefaultLoadEventListener extends AbstractLockUpgradeEventListener i
} }
final Class idClass = persister.getIdentifierType().getReturnedClass(); 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 ); checkIdClass( persister, event, loadType, idClass );
} }

View File

@ -39,7 +39,7 @@ import static org.junit.Assert.assertEquals;
/** /**
* @author Chris Cranford * @author Chris Cranford
*/ */
@TestForIssue(jiraKey = "HHH-12826") @TestForIssue(jiraKey = "HHH-12826 and HHH-12846")
public class CommitFlushCollectionTest extends BaseEnversJPAFunctionalTestCase { public class CommitFlushCollectionTest extends BaseEnversJPAFunctionalTestCase {
@MappedSuperclass @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 entityId1;
private Long entityId2; private Long entityId2;
@ -192,18 +224,25 @@ public class CommitFlushCollectionTest extends BaseEnversJPAFunctionalTestCase {
public void initData() { public void initData() {
// This failed when using Envers. // This failed when using Envers.
entityId1 = persistDocument( FlushModeType.COMMIT ); entityId1 = persistDocument( FlushModeType.COMMIT );
// This worked // This worked
entityId2 = persistDocument( FlushModeType.AUTO ); entityId2 = persistDocument( FlushModeType.AUTO );
// This failed
mergeDocument( FlushModeType.COMMIT, entityId1 );
// This worked
mergeDocument( FlushModeType.AUTO, entityId2 );
} }
@Test @Test
public void testPersistWithFlushModeCommit() { public void testWithFlushModeCommit() {
assertEquals( Arrays.asList( 1 ), getAuditReader().getRevisions( DocumentA.class, entityId1 ) ); assertEquals( Arrays.asList( 1, 3 ), getAuditReader().getRevisions( DocumentA.class, entityId1 ) );
} }
@Test @Test
@Priority(1) @Priority(1)
public void testPersistWithFlushmodeAuto() { public void testWithFlushModeAuto() {
assertEquals( Arrays.asList( 2 ), getAuditReader().getRevisions( DocumentA.class, entityId2 ) ); assertEquals( Arrays.asList( 2, 4 ), getAuditReader().getRevisions( DocumentA.class, entityId2 ) );
} }
} }