Skip to content

Commit 6880f73

Browse files
dreab8sebersole
authored andcommitted
HHH-18842 CollectionType.replace() breaks if target is PersistentCollection, but not instance of Collection
1 parent 2ba2695 commit 6880f73

File tree

3 files changed

+39
-4
lines changed

3 files changed

+39
-4
lines changed

hibernate-core/src/main/java/org/hibernate/collection/spi/PersistentArrayHolder.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import java.io.Serializable;
88
import java.lang.reflect.Array;
99
import java.util.ArrayList;
10+
import java.util.Arrays;
1011
import java.util.Collection;
1112
import java.util.Collections;
1213
import java.util.Iterator;
@@ -92,6 +93,9 @@ public boolean isSnapshotEmpty(Serializable snapshot) {
9293
public Collection getOrphans(Serializable snapshot, String entityName) throws HibernateException {
9394
final Object[] sn = (Object[]) snapshot;
9495
final Object[] arr = (Object[]) array;
96+
if ( arr.length == 0 ) {
97+
return Arrays.asList( sn );
98+
}
9599
final ArrayList result = new ArrayList();
96100
Collections.addAll( result, sn );
97101
for ( int i=0; i<sn.length; i++ ) {

hibernate-core/src/main/java/org/hibernate/engine/internal/Cascade.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -601,10 +601,20 @@ private static <T> void cascadeCollectionElements(
601601
}
602602
}
603603

604+
// a newly instantiated collection can't have orphans
605+
final PersistentCollection<?> persistentCollection;
606+
if ( child instanceof PersistentCollection<?> pc ) {
607+
persistentCollection = pc;
608+
}
609+
else {
610+
persistentCollection = eventSource.getPersistenceContext()
611+
.getCollectionHolder( child );
612+
}
613+
604614
final boolean deleteOrphans = style.hasOrphanDelete()
605615
&& action.deleteOrphans()
606616
&& elemType instanceof EntityType
607-
&& child instanceof PersistentCollection<?> persistentCollection
617+
&& persistentCollection != null
608618
// a newly instantiated collection can't have orphans
609619
&& !persistentCollection.isNewlyInstantiated();
610620

@@ -617,7 +627,7 @@ private static <T> void cascadeCollectionElements(
617627
// 1. newly instantiated collections
618628
// 2. arrays (we can't track orphans for detached arrays)
619629
final String entityName = collectionType.getAssociatedEntityName( eventSource.getFactory() );
620-
deleteOrphans( eventSource, entityName, (PersistentCollection<?>) child );
630+
deleteOrphans( eventSource, entityName, persistentCollection );
621631

622632
if ( traceEnabled ) {
623633
LOG.tracev( "Done deleting orphans for collection: {0}", collectionType.getRole() );

hibernate-core/src/main/java/org/hibernate/type/CollectionType.java

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.hibernate.Internal;
2525
import org.hibernate.MappingException;
2626
import org.hibernate.collection.spi.AbstractPersistentCollection;
27+
import org.hibernate.collection.spi.PersistentArrayHolder;
2728
import org.hibernate.collection.spi.PersistentCollection;
2829
import org.hibernate.engine.spi.CollectionEntry;
2930
import org.hibernate.engine.spi.CollectionKey;
@@ -634,11 +635,31 @@ public Object replace(
634635
if ( target == null ) {
635636
return null;
636637
}
637-
if ( target instanceof PersistentCollection ) {
638-
final Collection collection = (Collection) target;
638+
if ( target instanceof Collection<?> collection ) {
639639
collection.clear();
640640
return collection;
641641
}
642+
else if ( target instanceof Map<?,?> map ) {
643+
map.clear();
644+
return map;
645+
}
646+
else {
647+
final PersistenceContext persistenceContext = session.getPersistenceContext();
648+
final PersistentCollection<?> collectionHolder = persistenceContext
649+
.getCollectionHolder( target );
650+
if ( collectionHolder != null ) {
651+
if ( collectionHolder instanceof PersistentArrayHolder<?> persistentArrayHolder ) {
652+
persistenceContext.removeCollectionHolder( target );
653+
persistentArrayHolder.beginRead();
654+
persistentArrayHolder.injectLoadedState( persistenceContext.getCollectionEntry( collectionHolder ).getLoadedPersister().getAttributeMapping(), null );
655+
persistentArrayHolder.endRead();
656+
persistentArrayHolder.dirty();
657+
persistenceContext.addCollectionHolder( collectionHolder );
658+
return persistentArrayHolder.getArray();
659+
}
660+
}
661+
}
662+
642663
return null;
643664
}
644665
if ( !Hibernate.isInitialized( original ) ) {

0 commit comments

Comments
 (0)