diff --git a/hibernate-core/src/main/java/org/hibernate/collection/spi/PersistentArrayHolder.java b/hibernate-core/src/main/java/org/hibernate/collection/spi/PersistentArrayHolder.java index 778dce7341..4e718070bb 100644 --- a/hibernate-core/src/main/java/org/hibernate/collection/spi/PersistentArrayHolder.java +++ b/hibernate-core/src/main/java/org/hibernate/collection/spi/PersistentArrayHolder.java @@ -9,6 +9,7 @@ package org.hibernate.collection.spi; 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; @@ -94,6 +95,9 @@ public class PersistentArrayHolder extends AbstractPersistentCollection { 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 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(); @@ -637,7 +647,7 @@ public final class Cascade { // 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() ); diff --git a/hibernate-core/src/main/java/org/hibernate/type/CollectionType.java b/hibernate-core/src/main/java/org/hibernate/type/CollectionType.java index b127e764b2..ef2c37f242 100644 --- a/hibernate-core/src/main/java/org/hibernate/type/CollectionType.java +++ b/hibernate-core/src/main/java/org/hibernate/type/CollectionType.java @@ -25,6 +25,7 @@ import org.hibernate.Incubating; 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; @@ -641,11 +642,36 @@ public abstract class CollectionType extends AbstractType implements Association 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 ) ) {