Skip to content

Commit

Permalink
HHH-18842 CollectionType.replace() breaks if target is PersistentColl…
Browse files Browse the repository at this point in the history
…ection, but not instance of Collection
  • Loading branch information
dreab8 committed Nov 21, 2024
1 parent e094b3c commit 3dfb973
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.io.Serializable;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
Expand Down Expand Up @@ -94,6 +95,9 @@ public boolean isSnapshotEmpty(Serializable snapshot) {
public Collection getOrphans(Serializable snapshot, String entityName) throws HibernateException {
final Object[] sn = (Object[]) snapshot;
final Object[] arr = (Object[]) array;
if ( arr.length == 0 ) {
return Arrays.asList( sn );
}
final ArrayList result = new ArrayList();
Collections.addAll( result, sn );
for ( int i=0; i<sn.length; i++ ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -621,12 +621,22 @@ private static <T> void cascadeCollectionElements(
}
}

// a newly instantiated collection can't have orphans
final PersistentCollection<?> persistentCollection;
if ( child instanceof PersistentCollection<?> ) {
persistentCollection = (PersistentCollection<?>) child;
}
else {
persistentCollection = eventSource.getPersistenceContext()
.getCollectionHolder( child );
}

final boolean deleteOrphans = style.hasOrphanDelete()
&& action.deleteOrphans()
&& elemType instanceof EntityType
&& child instanceof PersistentCollection
&& persistentCollection != null
// a newly instantiated collection can't have orphans
&& ! ( (PersistentCollection<?>) child ).isNewlyInstantiated();
&& !persistentCollection.isNewlyInstantiated();

if ( deleteOrphans ) {
final boolean traceEnabled = LOG.isTraceEnabled();
Expand All @@ -637,7 +647,7 @@ private static <T> void cascadeCollectionElements(
// 1. newly instantiated collections
// 2. arrays (we can't track orphans for detached arrays)
final String entityName = collectionType.getAssociatedEntityName( eventSource.getFactory() );
deleteOrphans( eventSource, entityName, (PersistentCollection<?>) child );
deleteOrphans( eventSource, entityName, persistentCollection );

if ( traceEnabled ) {
LOG.tracev( "Done deleting orphans for collection: {0}", collectionType.getRole() );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import org.hibernate.Internal;
import org.hibernate.MappingException;
import org.hibernate.collection.spi.AbstractPersistentCollection;
import org.hibernate.collection.spi.PersistentArrayHolder;
import org.hibernate.collection.spi.PersistentCollection;
import org.hibernate.engine.spi.CollectionEntry;
import org.hibernate.engine.spi.CollectionKey;
Expand Down Expand Up @@ -641,11 +642,36 @@ public Object replace(
if ( target == null ) {
return null;
}
if ( target instanceof PersistentCollection ) {
final Collection collection = (Collection) target;
collection.clear();
return collection;
if ( target instanceof Collection<?> ) {
( (Collection<?>) target ).clear();
return target;
}
else if ( target instanceof Map<?, ?> ) {
( (Map<?, ?>) target ).clear();
return target;
}
else {
final PersistenceContext persistenceContext = session.getPersistenceContext();
final PersistentCollection<?> collectionHolder = persistenceContext
.getCollectionHolder( target );
if ( collectionHolder != null ) {
if ( collectionHolder instanceof PersistentArrayHolder<?> ) {
PersistentArrayHolder<?> persistentArrayHolder = (PersistentArrayHolder<?>) collectionHolder;
persistenceContext.removeCollectionHolder( target );
persistentArrayHolder.beginRead();
persistentArrayHolder.injectLoadedState(
persistenceContext.getCollectionEntry( collectionHolder )
.getLoadedPersister()
.getAttributeMapping(), null
);
persistentArrayHolder.endRead();
persistentArrayHolder.dirty();
persistenceContext.addCollectionHolder( collectionHolder );
return persistentArrayHolder.getArray();
}
}
}

return null;
}
if ( !Hibernate.isInitialized( original ) ) {
Expand Down

0 comments on commit 3dfb973

Please sign in to comment.