commit 9ca50199408e528ef10d7b6019f3cfcea42dfec3
Author: Andreas Müller <a.mueller@bgbm.org>
Date:   Tue Aug 25 10:47:16 2020 +0200

    ref #9204 update overridden AbstractPersistentCollection class to hibernate 5.1.17

diff --git a/eu.etaxonomy.taxeditor.cdmlib/src/main/java/org/hibernate/collection/internal/AbstractPersistentCollection.java b/eu.etaxonomy.taxeditor.cdmlib/src/main/java/org/hibernate/collection/internal/AbstractPersistentCollection.java
index a6b66ad47..9d3d9a1b3 100644
--- a/eu.etaxonomy.taxeditor.cdmlib/src/main/java/org/hibernate/collection/internal/AbstractPersistentCollection.java
+++ b/eu.etaxonomy.taxeditor.cdmlib/src/main/java/org/hibernate/collection/internal/AbstractPersistentCollection.java
@@ -34,13 +34,20 @@ import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.ListIterator;
+import java.util.Map;
 
 import javax.naming.NamingException;
 
 import org.hibernate.AssertionFailure;
+import org.hibernate.FlushMode;
 import org.hibernate.HibernateException;
 import org.hibernate.LazyInitializationException;
 import org.hibernate.Session;
+import org.hibernate.collection.internal.AbstractPersistentCollection.DelayedOperation;
+import org.hibernate.collection.internal.AbstractPersistentCollection.IteratorProxy;
+import org.hibernate.collection.internal.AbstractPersistentCollection.LazyInitializationWork;
+import org.hibernate.collection.internal.AbstractPersistentCollection.ListIteratorProxy;
+import org.hibernate.collection.internal.AbstractPersistentCollection.ValueDelayedOperation;
 import org.hibernate.collection.spi.PersistentCollection;
 import org.hibernate.engine.internal.ForeignKeys;
 import org.hibernate.engine.spi.CollectionEntry;
@@ -49,6 +56,8 @@ import org.hibernate.engine.spi.SessionFactoryImplementor;
 import org.hibernate.engine.spi.SessionImplementor;
 import org.hibernate.engine.spi.Status;
 import org.hibernate.engine.spi.TypedValue;
+import org.hibernate.internal.CoreLogging;
+import org.hibernate.internal.CoreMessageLogger;
 import org.hibernate.internal.SessionFactoryRegistry;
 import org.hibernate.internal.util.MarkerObject;
 import org.hibernate.internal.util.collections.EmptyIterator;
@@ -56,7 +65,14 @@ import org.hibernate.internal.util.collections.IdentitySet;
 import org.hibernate.persister.collection.CollectionPersister;
 import org.hibernate.persister.entity.EntityPersister;
 import org.hibernate.pretty.MessageHelper;
+import org.hibernate.type.CompositeType;
+import org.hibernate.type.IntegerType;
+import org.hibernate.type.LongType;
+import org.hibernate.type.PostgresUUIDType;
+import org.hibernate.type.StringType;
 import org.hibernate.type.Type;
+import org.hibernate.type.UUIDBinaryType;
+import org.hibernate.type.UUIDCharType;
 import org.jboss.logging.Logger;
 
 import eu.etaxonomy.cdm.api.application.CdmApplicationRemoteConfiguration;
@@ -68,17 +84,15 @@ import eu.etaxonomy.taxeditor.service.ICachedCommonService;
 /**
  * Base class implementing {@link org.hibernate.collection.spi.PersistentCollection}
  *
- * This a extended copy of the original class from hibernate. It has been extended to
+ * This is an extended copy of the original class from hibernate. It has been extended to
  * allow making remote service calls to spring httpinvoker services (see section at the bottom
  * of this class).
  *
- *
  * @author Gavin King
  * @author Cherian Mathew
  */
 public abstract class AbstractPersistentCollection implements Serializable, PersistentCollection {
-	private static final Logger log = Logger.getLogger( AbstractPersistentCollection.class );
-
+	
 	/**
 	 * <b>IMPORTANT:</b><br>
 	 * This serialVersionUID must be kept in sync with the serialVersionUID which is generated
@@ -97,9 +111,12 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
 	 * The correct <code>serialVersionUID</code> is the <code>stream classdesc serialVersionUID</code>
 	 * from the error message.
 	 */
-	private static final long serialVersionUID = 2742261122392386159L;
+	private static final long serialVersionUID = 7094296207968006972L;
+
+	private static final CoreMessageLogger LOG = CoreLogging.messageLogger( AbstractPersistentCollection.class );
 
 	private transient SessionImplementor session;
+	private boolean isTempSession = false;
 	private boolean initialized;
 	private transient List<DelayedOperation> operationQueue;
 	private transient boolean directlyAccessible;
@@ -115,50 +132,58 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
 	private Serializable storedSnapshot;
 
 	private String sessionFactoryUuid;
-	private boolean specjLazyLoad = false;
+	private boolean allowLoadOutsideTransaction;
+
+	/**
+	 * Not called by Hibernate, but used by non-JDK serialization,
+	 * eg. SOAP libraries.
+	 */
+	public AbstractPersistentCollection() {
+	}
+
+	protected AbstractPersistentCollection(SessionImplementor session) {
+		this.session = session;
+	}
 
 	@Override
-    public final String getRole() {
+	public final String getRole() {
 		return role;
 	}
 
 	@Override
-    public final Serializable getKey() {
+	public final Serializable getKey() {
 		return key;
 	}
 
 	@Override
-    public final boolean isUnreferenced() {
+	public final boolean isUnreferenced() {
 		return role == null;
 	}
 
 	@Override
-    public final boolean isDirty() {
+	public final boolean isDirty() {
 		return dirty;
 	}
 
 	@Override
-    public final void clearDirty() {
+	public final void clearDirty() {
 		dirty = false;
 	}
 
 	@Override
-    public final void dirty() {
+	public final void dirty() {
 		dirty = true;
 	}
 
 	@Override
-    public final Serializable getStoredSnapshot() {
+	public final Serializable getStoredSnapshot() {
 		return storedSnapshot;
 	}
 
 	//Careful: these methods do not initialize the collection.
 
-	/**
-	 * Is the initialized collection empty?
-	 */
 	@Override
-    public abstract boolean empty();
+	public abstract boolean empty();
 
 	/**
 	 * Called by any read-only method of the collection interface
@@ -177,101 +202,101 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
 				return true;
 			}
 			else {
-				// In remoting we are sure that session is null
-				// both when using property paths and switching off conversations
-				if(session == null && remoting) {
-					log.info("--> readSize, of " + getRole() + " with key " + getKey());
-					read();
-				} else {
-					boolean isExtraLazy = withTemporarySessionIfNeeded(
-							new LazyInitializationWork<Boolean>() {
-								@Override
-								public Boolean doWork() {
-									CollectionEntry entry = session.getPersistenceContext().getCollectionEntry( AbstractPersistentCollection.this );
-
-									if ( entry != null ) {
-										CollectionPersister persister = entry.getLoadedPersister();
-										if ( persister.isExtraLazy() ) {
-											if ( hasQueuedOperations() ) {
-												session.flush();
-											}
-											cachedSize = persister.getSize( entry.getLoadedKey(), session );
-											return true;
-										}
-										else {
-											read();
+				final boolean isExtraLazy = withTemporarySessionIfNeeded(
+						new LazyInitializationWork<Boolean>() {
+							@Override
+							public Boolean doWork() {
+								final CollectionEntry entry = session.getPersistenceContext().getCollectionEntry( AbstractPersistentCollection.this );
+
+								if ( entry != null ) {
+									final CollectionPersister persister = entry.getLoadedPersister();
+									if ( persister.isExtraLazy() ) {
+										if ( hasQueuedOperations() ) {
+											session.flush();
 										}
+										cachedSize = persister.getSize( entry.getLoadedKey(), session );
+										return true;
 									}
-									else{
-										throwLazyInitializationExceptionIfNotConnected();
+									else {
+										read();
 									}
-									return false;
 								}
+								else{
+									throwLazyInitializationExceptionIfNotConnected();
+								}
+								return false;
 							}
-							);
-					if ( isExtraLazy ) {
-						return true;
-					}
+						}
+				);
+				if ( isExtraLazy ) {
+					return true;
 				}
 			}
 		}
 		return false;
 	}
 
+	/**
+	 * TBH not sure why this is public
+	 *
+	 * @param <T> The java type of the return for this LazyInitializationWork
+	 */
 	public static interface LazyInitializationWork<T> {
+		/**
+		 * Do the represented work and return the result.
+		 *
+		 * @return The result
+		 */
 		public T doWork();
 	}
 
 	private <T> T withTemporarySessionIfNeeded(LazyInitializationWork<T> lazyInitializationWork) {
-		SessionImplementor originalSession = null;
-		boolean isTempSession = false;
-		boolean isJTA = false;
+		SessionImplementor tempSession = null;
 
 		if ( session == null ) {
-			if ( specjLazyLoad ) {
-				session = openTemporarySessionForLoading();
-				isTempSession = true;
+			if ( allowLoadOutsideTransaction ) {
+				tempSession = openTemporarySessionForLoading();
 			}
 			else {
 				throwLazyInitializationException( "could not initialize proxy - no Session" );
 			}
 		}
 		else if ( !session.isOpen() ) {
-			if ( specjLazyLoad ) {
-				originalSession = session;
-				session = openTemporarySessionForLoading();
-				isTempSession = true;
+			if ( allowLoadOutsideTransaction ) {
+				tempSession = openTemporarySessionForLoading();
 			}
 			else {
 				throwLazyInitializationException( "could not initialize proxy - the owning Session was closed" );
 			}
 		}
 		else if ( !session.isConnected() ) {
-			if ( specjLazyLoad ) {
-				originalSession = session;
-				session = openTemporarySessionForLoading();
-				isTempSession = true;
+			if ( allowLoadOutsideTransaction ) {
+				tempSession = openTemporarySessionForLoading();
 			}
 			else {
 				throwLazyInitializationException( "could not initialize proxy - the owning Session is disconnected" );
 			}
 		}
 
-		if ( isTempSession ) {
-			// TODO: On the next major release, add an
-			// 'isJTA' or 'getTransactionFactory' method to Session.
-			/*isJTA = session.getTransactionCoordinator()
-					.getTransactionContext().getTransactionEnvironment()
-					.getTransactionFactory()
-					.compatibleWithJtaSynchronization();*/
+
+		SessionImplementor originalSession = null;
+		boolean isJTA = false;
+
+		if ( tempSession != null ) {
+			isTempSession = true;
+			originalSession = session;
+			session = tempSession;
+
+
 			isJTA = session.getTransactionCoordinator().getTransactionCoordinatorBuilder().isJta();
+			
 			if ( !isJTA ) {
 				// Explicitly handle the transactions only if we're not in
 				// a JTA environment.  A lazy loading temporary session can
 				// be created even if a current session and transaction are
 				// open (ex: session.clear() was used).  We must prevent
 				// multiple transactions.
-				( ( Session) session ).beginTransaction();
+				( (Session) session ).beginTransaction();
 			}
 
 			session.getPersistenceContext().addUninitializedDetachedCollection(
@@ -284,18 +309,20 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
 			return lazyInitializationWork.doWork();
 		}
 		finally {
-			if ( isTempSession ) {
+			if ( tempSession != null ) {
 				// make sure the just opened temp session gets closed!
+				isTempSession = false;
+				session = originalSession;
+
 				try {
 					if ( !isJTA ) {
-						( ( Session) session ).getTransaction().commit();
+						( (Session) tempSession ).getTransaction().commit();
 					}
-					( (Session) session ).close();
+					( (Session) tempSession ).close();
 				}
 				catch (Exception e) {
-					log.warn( "Unable to close temporary session used to load lazy collection associated to no session" );
+					LOG.warn( "Unable to close temporary session used to load lazy collection associated to no session" );
 				}
-				session = originalSession;
 			}
 		}
 	}
@@ -305,41 +332,37 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
 			throwLazyInitializationException( "SessionFactory UUID not known to create temporary Session for loading" );
 		}
 
-		SessionFactoryImplementor sf = (SessionFactoryImplementor)
+		final SessionFactoryImplementor sf = (SessionFactoryImplementor)
 				SessionFactoryRegistry.INSTANCE.getSessionFactory( sessionFactoryUuid );
-		return (SessionImplementor) sf.openSession();
+		final SessionImplementor session = (SessionImplementor) sf.openSession();
+		session.getPersistenceContext().setDefaultReadOnly( true );
+		session.setFlushMode( FlushMode.MANUAL );
+		return session;
 	}
 
 	protected Boolean readIndexExistence(final Object index) {
 		if ( !initialized ) {
-			// In remoting we are sure that session is null
-			// both when using property paths and switching off conversations
-			if(session == null && remoting) {
-				log.info("--> readIndexExistence, of " + getRole() + " with key " + getKey());
-				read();
-			} else {
-				Boolean extraLazyExistenceCheck = withTemporarySessionIfNeeded(
-						new LazyInitializationWork<Boolean>() {
-							@Override
-							public Boolean doWork() {
-								CollectionEntry entry = session.getPersistenceContext().getCollectionEntry( AbstractPersistentCollection.this );
-								CollectionPersister persister = entry.getLoadedPersister();
-								if ( persister.isExtraLazy() ) {
-									if ( hasQueuedOperations() ) {
-										session.flush();
-									}
-									return persister.indexExists( entry.getLoadedKey(), index, session );
-								}
-								else {
-									read();
+			final Boolean extraLazyExistenceCheck = withTemporarySessionIfNeeded(
+					new LazyInitializationWork<Boolean>() {
+						@Override
+						public Boolean doWork() {
+							final CollectionEntry entry = session.getPersistenceContext().getCollectionEntry( AbstractPersistentCollection.this );
+							final CollectionPersister persister = entry.getLoadedPersister();
+							if ( persister.isExtraLazy() ) {
+								if ( hasQueuedOperations() ) {
+									session.flush();
 								}
-								return null;
+								return persister.indexExists( entry.getLoadedKey(), index, session );
+							}
+							else {
+								read();
 							}
+							return null;
 						}
-						);
-				if ( extraLazyExistenceCheck != null ) {
-					return extraLazyExistenceCheck;
-				}
+					}
+			);
+			if ( extraLazyExistenceCheck != null ) {
+				return extraLazyExistenceCheck;
 			}
 		}
 		return null;
@@ -347,35 +370,27 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
 
 	protected Boolean readElementExistence(final Object element) {
 		if ( !initialized ) {
-			// In remoting we are sure that session is null
-			// both when using property paths and switching off conversations
-			if(session == null && remoting) {
-				log.info("--> readElementExistence, of " + getRole() + " with key " + getKey());
-				read();
-
-			} else {
-				Boolean extraLazyExistenceCheck = withTemporarySessionIfNeeded(
-						new LazyInitializationWork<Boolean>() {
-							@Override
-							public Boolean doWork() {
-								CollectionEntry entry = session.getPersistenceContext().getCollectionEntry( AbstractPersistentCollection.this );
-								CollectionPersister persister = entry.getLoadedPersister();
-								if ( persister.isExtraLazy() ) {
-									if ( hasQueuedOperations() ) {
-										session.flush();
-									}
-									return persister.elementExists( entry.getLoadedKey(), element, session );
-								}
-								else {
-									read();
+			final Boolean extraLazyExistenceCheck = withTemporarySessionIfNeeded(
+					new LazyInitializationWork<Boolean>() {
+						@Override
+						public Boolean doWork() {
+							final CollectionEntry entry = session.getPersistenceContext().getCollectionEntry( AbstractPersistentCollection.this );
+							final CollectionPersister persister = entry.getLoadedPersister();
+							if ( persister.isExtraLazy() ) {
+								if ( hasQueuedOperations() ) {
+									session.flush();
 								}
-								return null;
+								return persister.elementExists( entry.getLoadedKey(), element, session );
 							}
+							else {
+								read();
+							}
+							return null;
 						}
-						);
-				if ( extraLazyExistenceCheck != null ) {
-					return extraLazyExistenceCheck;
-				}
+					}
+			);
+			if ( extraLazyExistenceCheck != null ) {
+				return extraLazyExistenceCheck;
 			}
 		}
 		return null;
@@ -385,41 +400,33 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
 
 	protected Object readElementByIndex(final Object index) {
 		if ( !initialized ) {
-			// In remoting we are sure that session is null
-			// both when using property paths and switching off conversations
-			if(session == null && remoting) {
-				log.info("--> readElementByIndex, of " + getRole() + " with key " + getKey());
-				read();
-
-			} else {
-				class ExtraLazyElementByIndexReader implements LazyInitializationWork {
-					private boolean isExtraLazy;
-					private Object element;
+			class ExtraLazyElementByIndexReader implements LazyInitializationWork {
+				private boolean isExtraLazy;
+				private Object element;
 
-					@Override
-					public Object doWork() {
-						CollectionEntry entry = session.getPersistenceContext().getCollectionEntry( AbstractPersistentCollection.this );
-						CollectionPersister persister = entry.getLoadedPersister();
-						isExtraLazy = persister.isExtraLazy();
-						if ( isExtraLazy ) {
-							if ( hasQueuedOperations() ) {
-								session.flush();
-							}
-							element = persister.getElementByIndex( entry.getLoadedKey(), index, session, owner );
-						}
-						else {
-							read();
+				@Override
+				public Object doWork() {
+					final CollectionEntry entry = session.getPersistenceContext().getCollectionEntry( AbstractPersistentCollection.this );
+					final CollectionPersister persister = entry.getLoadedPersister();
+					isExtraLazy = persister.isExtraLazy();
+					if ( isExtraLazy ) {
+						if ( hasQueuedOperations() ) {
+							session.flush();
 						}
-						return null;
+						element = persister.getElementByIndex( entry.getLoadedKey(), index, session, owner );
 					}
+					else {
+						read();
+					}
+					return null;
 				}
+			}
 
-				ExtraLazyElementByIndexReader reader = new ExtraLazyElementByIndexReader();
-				//noinspection unchecked
-				withTemporarySessionIfNeeded( reader );
-				if ( reader.isExtraLazy ) {
-					return reader.element;
-				}
+			final ExtraLazyElementByIndexReader reader = new ExtraLazyElementByIndexReader();
+			//noinspection unchecked
+			withTemporarySessionIfNeeded( reader );
+			if ( reader.isExtraLazy ) {
+				return reader.element;
 			}
 		}
 		return UNKNOWN;
@@ -430,10 +437,14 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
 		return cachedSize;
 	}
 
-	private boolean isConnectedToSession() {
-		return session != null &&
-				session.isOpen() &&
-				session.getPersistenceContext().containsCollection( this );
+	protected boolean isConnectedToSession() {
+		return session != null
+				&& session.isOpen()
+				&& session.getPersistenceContext().containsCollection( this );
+	}
+
+	protected boolean isInitialized() {
+		return initialized;
 	}
 
 	/**
@@ -450,9 +461,9 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
 	 */
 	@SuppressWarnings({"JavaDoc"})
 	protected boolean isOperationQueueEnabled() {
-		return !initialized &&
-				isConnectedToSession() &&
-				isInverseCollection();
+		return !initialized
+				&& isConnectedToSession()
+				&& isInverseCollection();
 	}
 
 	/**
@@ -462,9 +473,9 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
 	 */
 	@SuppressWarnings({"JavaDoc"})
 	protected boolean isPutQueueEnabled() {
-		return !initialized &&
-				isConnectedToSession() &&
-				isInverseOneToManyOrNoOrphanDelete();
+		return !initialized
+				&& isConnectedToSession()
+				&& isInverseOneToManyOrNoOrphanDelete();
 	}
 
 	/**
@@ -474,17 +485,17 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
 	 */
 	@SuppressWarnings({"JavaDoc"})
 	protected boolean isClearQueueEnabled() {
-		return !initialized &&
-				isConnectedToSession() &&
-				isInverseCollectionNoOrphanDelete();
+		return !initialized
+				&& isConnectedToSession()
+				&& isInverseCollectionNoOrphanDelete();
 	}
 
 	/**
 	 * Is this the "inverse" end of a bidirectional association?
 	 */
 	@SuppressWarnings({"JavaDoc"})
-	private boolean isInverseCollection() {
-		CollectionEntry ce = session.getPersistenceContext().getCollectionEntry( this );
+	protected boolean isInverseCollection() {
+		final CollectionEntry ce = session.getPersistenceContext().getCollectionEntry( this );
 		return ce != null && ce.getLoadedPersister().isInverse();
 	}
 
@@ -493,9 +504,10 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
 	 * no orphan delete enabled?
 	 */
 	@SuppressWarnings({"JavaDoc"})
-	private boolean isInverseCollectionNoOrphanDelete() {
-		CollectionEntry ce = session.getPersistenceContext().getCollectionEntry( this );
-		return ce != null &&
+	protected boolean isInverseCollectionNoOrphanDelete() {
+		final CollectionEntry ce = session.getPersistenceContext().getCollectionEntry( this );
+		return ce != null
+				&&
 				ce.getLoadedPersister().isInverse() &&
 				!ce.getLoadedPersister().hasOrphanDelete();
 	}
@@ -505,12 +517,11 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
 	 * of a collection with no orphan delete?
 	 */
 	@SuppressWarnings({"JavaDoc"})
-	private boolean isInverseOneToManyOrNoOrphanDelete() {
-		CollectionEntry ce = session.getPersistenceContext().getCollectionEntry( this );
-		return ce != null && ce.getLoadedPersister().isInverse() && (
-				ce.getLoadedPersister().isOneToMany() ||
-						!ce.getLoadedPersister().hasOrphanDelete()
-		);
+	protected boolean isInverseOneToManyOrNoOrphanDelete() {
+		final CollectionEntry ce = session.getPersistenceContext().getCollectionEntry( this );
+		return ce != null
+				&& ce.getLoadedPersister().isInverse()
+				&& ( ce.getLoadedPersister().isOneToMany() || !ce.getLoadedPersister().hasOrphanDelete() );
 	}
 
 	/**
@@ -522,7 +533,22 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
 			operationQueue = new ArrayList<DelayedOperation>( 10 );
 		}
 		operationQueue.add( operation );
-		dirty = true; //needed so that we remove this collection from the second-level cache
+		//needed so that we remove this collection from the second-level cache
+		dirty = true;
+	}
+
+	/**
+	 * Replace entity instances with copy in {@code copyCache}/.
+	 *
+	 * @param copyCache - mapping from entity in the process of being
+	 *                    merged to managed copy.
+	 */
+	public final void replaceQueuedOperationValues(CollectionPersister persister, Map copyCache) {
+		for ( DelayedOperation operation : operationQueue ) {
+			if ( ValueDelayedOperation.class.isInstance( operation ) ) {
+				( (ValueDelayedOperation) operation ).replace( persister, copyCache );
+			}
+		}
 	}
 
 	/**
@@ -535,66 +561,39 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
 		}
 	}
 
-	/**
-	 * After flushing, re-init snapshot state.
-	 */
 	@Override
-    public void setSnapshot(Serializable key, String role, Serializable snapshot) {
+	public void setSnapshot(Serializable key, String role, Serializable snapshot) {
 		this.key = key;
 		this.role = role;
 		this.storedSnapshot = snapshot;
 	}
 
-	/**
-	 * After flushing, clear any "queued" additions, since the
-	 * database state is now synchronized with the memory state.
-	 */
 	@Override
-    public void postAction() {
+	public void postAction() {
 		operationQueue = null;
 		cachedSize = -1;
 		clearDirty();
 	}
 
-	/**
-	 * Not called by Hibernate, but used by non-JDK serialization,
-	 * eg. SOAP libraries.
-	 */
-	public AbstractPersistentCollection() {
-	}
-
-	protected AbstractPersistentCollection(SessionImplementor session) {
-		this.session = session;
-	}
-
-	/**
-	 * return the user-visible collection (or array) instance
-	 */
 	@Override
-    public Object getValue() {
+	public Object getValue() {
 		return this;
 	}
 
-	/**
-	 * Called just before reading any rows from the JDBC result set
-	 */
 	@Override
-    public void beginRead() {
+	public void beginRead() {
 		// override on some subclasses
 		initializing = true;
 	}
 
-	/**
-	 * Called after reading all rows from the JDBC result set
-	 */
 	@Override
-    public boolean endRead() {
+	public boolean endRead() {
 		//override on some subclasses
 		return afterInitialize();
 	}
 
 	@Override
-    public boolean afterInitialize() {
+	public boolean afterInitialize() {
 		setInitialized();
 		//do this bit after setting initialized to true or it will recurse
 		if ( operationQueue != null ) {
@@ -617,25 +616,19 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
 	 * @throws LazyInitializationException if we cannot initialize
 	 */
 	protected final void initialize(final boolean writing) {
-	    if ( initialized ) {
-	        return;
-	    }
-
-	    // In remoting we are sure that session is null
-	    // both when using property paths and switching off conversations
-	    if(session == null && remoting) {
-	        remoteInitialize();
-	    } else {
-	        withTemporarySessionIfNeeded(
-	                new LazyInitializationWork<Object>() {
-	                    @Override
-	                    public Object doWork() {
-	                        session.initializeCollection( AbstractPersistentCollection.this, writing );
-	                        return null;
-	                    }
-	                }
-	                );
-	    }
+		if ( initialized ) {
+			return;
+		}
+
+		withTemporarySessionIfNeeded(
+				new LazyInitializationWork<Object>() {
+					@Override
+					public Object doWork() {
+						session.initializeCollection( AbstractPersistentCollection.this, writing );
+						return null;
+					}
+				}
+		);
 	}
 
 	private void throwLazyInitializationExceptionIfNotConnected() {
@@ -664,77 +657,55 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
 		this.directlyAccessible = directlyAccessible;
 	}
 
-	/**
-	 * Could the application possibly have a direct reference to
-	 * the underlying collection implementation?
-	 */
 	@Override
-    public boolean isDirectlyAccessible() {
+	public boolean isDirectlyAccessible() {
 		return directlyAccessible;
 	}
 
-	/**
-	 * Disassociate this collection from the given session.
-	 *
-	 * @return true if this was currently associated with the given session
-	 */
 	@Override
-    public final boolean unsetSession(SessionImplementor currentSession) {
-		prepareForPossibleSpecialSpecjInitialization();
+	public final boolean unsetSession(SessionImplementor currentSession) {
+		prepareForPossibleLoadingOutsideTransaction();
 		if ( currentSession == this.session ) {
-			this.session = null;
+			if ( !isTempSession ) {
+				this.session = null;
+			}
 			return true;
 		}
 		else {
+			if ( this.session != null ) {
+				LOG.logCannotUnsetUnexpectedSessionInCollection( generateUnexpectedSessionStateMessage( currentSession ) );
+			}
 			return false;
 		}
 	}
 
-	protected void prepareForPossibleSpecialSpecjInitialization() {
+	protected void prepareForPossibleLoadingOutsideTransaction() {
 		if ( session != null ) {
-			specjLazyLoad = session.getFactory().getSettings().isInitializeLazyStateOutsideTransactionsEnabled();
+			allowLoadOutsideTransaction = session.getFactory().getSessionFactoryOptions().isInitializeLazyStateOutsideTransactionsEnabled();
 
-			if ( specjLazyLoad && sessionFactoryUuid == null ) {
-				try {
-					sessionFactoryUuid = (String) session.getFactory().getReference().get( "uuid" ).getContent();
-				}
-				catch (NamingException e) {
-					//not much we can do if this fails...
-				}
+			if ( allowLoadOutsideTransaction && sessionFactoryUuid == null ) {
+				sessionFactoryUuid = session.getFactory().getUuid();
 			}
 		}
 	}
 
-
-	/**
-	 * Associate the collection with the given session.
-	 *
-	 * @return false if the collection was already associated with the session
-	 *
-	 * @throws HibernateException if the collection was already associated
-	 * with another open session
-	 */
 	@Override
-    public final boolean setCurrentSession(SessionImplementor session) throws HibernateException {
+	public final boolean setCurrentSession(SessionImplementor session) throws HibernateException {
 		if ( session == this.session ) {
 			return false;
 		}
 		else {
-			if ( isConnectedToSession() ) {
-				CollectionEntry ce = session.getPersistenceContext().getCollectionEntry( this );
-				if ( ce == null ) {
+			if ( this.session != null ) {
+				final String msg = generateUnexpectedSessionStateMessage( session );
+				if ( isConnectedToSession() ) {
 					throw new HibernateException(
-							"Illegal attempt to associate a collection with two open sessions"
+							"Illegal attempt to associate a collection with two open sessions. " + msg
 					);
 				}
 				else {
-					throw new HibernateException(
-							"Illegal attempt to associate a collection with two open sessions: " +
-									MessageHelper.collectionInfoString(
-											ce.getLoadedPersister(), this,
-											ce.getLoadedKey(), session
-									)
-					);
+					LOG.logUnexpectedSessionInCollectionNotConnected( msg );
+					this.session = session;
+					return true;
 				}
 			}
 			else {
@@ -744,31 +715,80 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
 		}
 	}
 
-	/**
-	 * Do we need to completely recreate this collection when it changes?
-	 */
+	private String generateUnexpectedSessionStateMessage(SessionImplementor session) {
+		// NOTE: If this.session != null, this.session may be operating on this collection
+		// (e.g., by changing this.role, this.key, or even this.session) in a different thread.
+
+		// Grab the current role and key (it can still get changed by this.session...)
+		// If this collection is connected to this.session, then this.role and this.key should
+		// be consistent with the CollectionEntry in this.session (as long as this.session doesn't
+		// change it). Don't access the CollectionEntry in this.session because that could result
+		// in multi-threaded access to this.session.
+		final String roleCurrent = role;
+		final Serializable keyCurrent = key;
+
+		final StringBuilder sb = new StringBuilder( "Collection : " );
+		if ( roleCurrent != null ) {
+			sb.append( MessageHelper.collectionInfoString( roleCurrent, keyCurrent ) );
+		}
+		else {
+			final CollectionEntry ce = session.getPersistenceContext().getCollectionEntry( this );
+			if ( ce != null ) {
+				sb.append(
+						MessageHelper.collectionInfoString(
+								ce.getLoadedPersister(),
+								this,
+								ce.getLoadedKey(),
+								session
+						)
+				);
+			}
+			else {
+				sb.append( "<unknown>" );
+			}
+		}
+		// only include the collection contents if debug logging
+		if ( LOG.isDebugEnabled() ) {
+			final String collectionContents = wasInitialized() ? toString() : "<uninitialized>";
+			sb.append( "\nCollection contents: [" ).append( collectionContents ).append( "]" );
+		}
+		return sb.toString();
+	}
+
 	@Override
-    public boolean needsRecreate(CollectionPersister persister) {
+	public boolean needsRecreate(CollectionPersister persister) {
+		// Workaround for situations like HHH-7072.  If the collection element is a component that consists entirely
+		// of nullable properties, we currently have to forcefully recreate the entire collection.  See the use
+		// of hasNotNullableColumns in the AbstractCollectionPersister constructor for more info.  In order to delete
+		// row-by-row, that would require SQL like "WHERE ( COL = ? OR ( COL is null AND ? is null ) )", rather than
+		// the current "WHERE COL = ?" (fails for null for most DBs).  Note that
+		// the param would have to be bound twice.  Until we eventually add "parameter bind points" concepts to the
+		// AST in ORM 5+, handling this type of condition is either extremely difficult or impossible.  Forcing
+		// recreation isn't ideal, but not really any other option in ORM 4.
+		// Selecting a type used in where part of update statement
+		// (must match condidion in org.hibernate.persister.collection.BasicCollectionPersister.doUpdateRows).
+		// See HHH-9474
+		Type whereType;
+		if ( persister.hasIndex() ) {
+			whereType = persister.getIndexType();
+		}
+		else {
+			whereType = persister.getElementType();
+		}
+		if ( whereType instanceof CompositeType ) {
+			CompositeType componentIndexType = (CompositeType) whereType;
+			return !componentIndexType.hasNotNullProperty();
+		}
 		return false;
 	}
 
-	/**
-	 * To be called internally by the session, forcing
-	 * immediate initialization.
-	 */
 	@Override
-    public final void forceInitialization() throws HibernateException {
+	public final void forceInitialization() throws HibernateException {
 		if ( !initialized ) {
 			if ( initializing ) {
 				throw new AssertionFailure( "force initialize loading collection" );
 			}
-			if ( session == null ) {
-				throw new HibernateException( "collection is not associated with any session" );
-			}
-			if ( !session.isConnected() ) {
-				throw new HibernateException( "disconnected session" );
-			}
-			session.initializeCollection( this, false );
+			initialize( false );
 		}
 	}
 
@@ -781,48 +801,39 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
 		return session.getPersistenceContext().getSnapshot( this );
 	}
 
-	/**
-	 * Is this instance initialized?
-	 */
 	@Override
-    public final boolean wasInitialized() {
+	public final boolean wasInitialized() {
 		return initialized;
 	}
 
 	@Override
-    public boolean isRowUpdatePossible() {
+	public boolean isRowUpdatePossible() {
 		return true;
 	}
 
-	/**
-	 * Does this instance have any "queued" additions?
-	 */
 	@Override
-    public final boolean hasQueuedOperations() {
+	public final boolean hasQueuedOperations() {
 		return operationQueue != null;
 	}
 
-	/**
-	 * Iterate the "queued" additions
-	 */
 	@Override
-    public final Iterator queuedAdditionIterator() {
+	public final Iterator queuedAdditionIterator() {
 		if ( hasQueuedOperations() ) {
 			return new Iterator() {
-				int i = 0;
+				private int index;
 
 				@Override
-                public Object next() {
-					return operationQueue.get( i++ ).getAddedInstance();
+				public Object next() {
+					return operationQueue.get( index++ ).getAddedInstance();
 				}
 
 				@Override
-                public boolean hasNext() {
-					return i < operationQueue.size();
+				public boolean hasNext() {
+					return index < operationQueue.size();
 				}
 
 				@Override
-                public void remove() {
+				public void remove() {
 					throw new UnsupportedOperationException();
 				}
 			};
@@ -832,15 +843,12 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
 		}
 	}
 
-	/**
-	 * Iterate the "queued" additions
-	 */
 	@Override
-    @SuppressWarnings({"unchecked"})
+	@SuppressWarnings({"unchecked"})
 	public final Collection getQueuedOrphans(String entityName) {
 		if ( hasQueuedOperations() ) {
-			Collection additions = new ArrayList( operationQueue.size() );
-			Collection removals = new ArrayList( operationQueue.size() );
+			final Collection additions = new ArrayList( operationQueue.size() );
+			final Collection removals = new ArrayList( operationQueue.size() );
 			for ( DelayedOperation operation : operationQueue ) {
 				additions.add( operation.getAddedInstance() );
 				removals.add( operation.getOrphan() );
@@ -852,31 +860,22 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
 		}
 	}
 
-	/**
-	 * Called before inserting rows, to ensure that any surrogate keys
-	 * are fully generated
-	 */
 	@Override
-    public void preInsert(CollectionPersister persister) throws HibernateException {
+	public void preInsert(CollectionPersister persister) throws HibernateException {
 	}
 
-	/**
-	 * Called after inserting a row, to fetch the natively generated id
-	 */
 	@Override
-    public void afterRowInsert(CollectionPersister persister, Object entry, int i) throws HibernateException {
+	public void afterRowInsert(CollectionPersister persister, Object entry, int i) throws HibernateException {
 	}
 
-	/**
-	 * get all "orphaned" elements
-	 */
 	@Override
-    public abstract Collection getOrphans(Serializable snapshot, String entityName) throws HibernateException;
+	public abstract Collection getOrphans(Serializable snapshot, String entityName) throws HibernateException;
 
 	/**
-	 * Get the current session
+	 * Get the session currently associated with this collection.
+	 *
+	 * @return The session
 	 */
-	@SuppressWarnings({"JavaDoc"})
 	public final SessionImplementor getSession() {
 		return session;
 	}
@@ -889,21 +888,20 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
 		}
 
 		@Override
-        public boolean hasNext() {
+		public boolean hasNext() {
 			return itr.hasNext();
 		}
 
 		@Override
-        public Object next() {
+		public Object next() {
 			return itr.next();
 		}
 
 		@Override
-        public void remove() {
+		public void remove() {
 			write();
 			itr.remove();
 		}
-
 	}
 
 	protected final class ListIteratorProxy implements ListIterator {
@@ -914,55 +912,54 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
 		}
 
 		@Override
-        @SuppressWarnings({"unchecked"})
+		@SuppressWarnings({"unchecked"})
 		public void add(Object o) {
 			write();
 			itr.add( o );
 		}
 
 		@Override
-        public boolean hasNext() {
+		public boolean hasNext() {
 			return itr.hasNext();
 		}
 
 		@Override
-        public boolean hasPrevious() {
+		public boolean hasPrevious() {
 			return itr.hasPrevious();
 		}
 
 		@Override
-        public Object next() {
+		public Object next() {
 			return itr.next();
 		}
 
 		@Override
-        public int nextIndex() {
+		public int nextIndex() {
 			return itr.nextIndex();
 		}
 
 		@Override
-        public Object previous() {
+		public Object previous() {
 			return itr.previous();
 		}
 
 		@Override
-        public int previousIndex() {
+		public int previousIndex() {
 			return itr.previousIndex();
 		}
 
 		@Override
-        public void remove() {
+		public void remove() {
 			write();
 			itr.remove();
 		}
 
 		@Override
-        @SuppressWarnings({"unchecked"})
+		@SuppressWarnings({"unchecked"})
 		public void set(Object o) {
 			write();
 			itr.set( o );
 		}
-
 	}
 
 	protected class SetProxy implements java.util.Set {
@@ -973,79 +970,81 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
 		}
 
 		@Override
-        @SuppressWarnings({"unchecked"})
+		@SuppressWarnings({"unchecked"})
 		public boolean add(Object o) {
 			write();
 			return set.add( o );
 		}
 
 		@Override
-        @SuppressWarnings({"unchecked"})
+		@SuppressWarnings({"unchecked"})
 		public boolean addAll(Collection c) {
 			write();
 			return set.addAll( c );
 		}
 
 		@Override
-        public void clear() {
+		public void clear() {
 			write();
 			set.clear();
 		}
 
 		@Override
-        public boolean contains(Object o) {
+		public boolean contains(Object o) {
 			return set.contains( o );
 		}
 
 		@Override
-        public boolean containsAll(Collection c) {
+		@SuppressWarnings("unchecked")
+		public boolean containsAll(Collection c) {
 			return set.containsAll( c );
 		}
 
 		@Override
-        public boolean isEmpty() {
+		public boolean isEmpty() {
 			return set.isEmpty();
 		}
 
 		@Override
-        public Iterator iterator() {
+		public Iterator iterator() {
 			return new IteratorProxy( set.iterator() );
 		}
 
 		@Override
-        public boolean remove(Object o) {
+		public boolean remove(Object o) {
 			write();
 			return set.remove( o );
 		}
 
 		@Override
-        public boolean removeAll(Collection c) {
+		@SuppressWarnings("unchecked")
+		public boolean removeAll(Collection c) {
 			write();
 			return set.removeAll( c );
 		}
 
 		@Override
-        public boolean retainAll(Collection c) {
+		@SuppressWarnings("unchecked")
+		public boolean retainAll(Collection c) {
 			write();
 			return set.retainAll( c );
 		}
 
 		@Override
-        public int size() {
+		public int size() {
 			return set.size();
 		}
 
 		@Override
-        public Object[] toArray() {
+		public Object[] toArray() {
 			return set.toArray();
 		}
 
 		@Override
-        @SuppressWarnings({"unchecked"})
+		@SuppressWarnings({"unchecked"})
 		public Object[] toArray(Object[] array) {
 			return set.toArray( array );
 		}
-
 	}
 
 	protected final class ListProxy implements java.util.List {
@@ -1095,6 +1094,7 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
 		}
 
 		@Override
+		@SuppressWarnings("unchecked")
 		public boolean containsAll(Collection c) {
 			return list.containsAll( c );
 		}
@@ -1147,12 +1147,14 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
 		}
 
 		@Override
+		@SuppressWarnings("unchecked")
 		public boolean removeAll(Collection c) {
 			write();
 			return list.removeAll( c );
 		}
 
 		@Override
+		@SuppressWarnings("unchecked")
 		public boolean retainAll(Collection c) {
 			write();
 			return list.retainAll( c );
@@ -1199,6 +1201,40 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
 		public Object getOrphan();
 	}
 
+	protected interface ValueDelayedOperation extends DelayedOperation {
+		void replace(CollectionPersister collectionPersister, Map copyCache);
+	}
+
+	protected abstract class AbstractValueDelayedOperation implements ValueDelayedOperation {
+		private Object addedValue;
+		private Object orphan;
+
+		protected AbstractValueDelayedOperation(Object addedValue, Object orphan) {
+			this.addedValue = addedValue;
+			this.orphan = orphan;
+		}
+
+		public void replace(CollectionPersister persister, Map copyCache) {
+			if ( addedValue != null ) {
+				addedValue = getReplacement( persister.getElementType(), addedValue, copyCache );
+			}
+		}
+
+		protected final Object getReplacement(Type type, Object current, Map copyCache) {
+			return type.replace( current, null, session, owner, copyCache );
+		}
+
+		@Override
+		public final Object getAddedInstance() {
+			return addedValue;
+		}
+
+		@Override
+		public final Object getOrphan() {
+			return orphan;
+		}
+	}
+
 	/**
 	 * Given a collection of entity instances that used to
 	 * belong to the collection, and a collection of instances
@@ -1213,34 +1249,37 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
 
 		// short-circuit(s)
 		if ( currentElements.size() == 0 ) {
-			return oldElements; // no new elements, the old list contains only Orphans
+			// no new elements, the old list contains only Orphans
+			return oldElements;
 		}
 		if ( oldElements.size() == 0 ) {
-			return oldElements; // no old elements, so no Orphans neither
+			// no old elements, so no Orphans neither
+			return oldElements;
 		}
 
 		final EntityPersister entityPersister = session.getFactory().getEntityPersister( entityName );
 		final Type idType = entityPersister.getIdentifierType();
+		final boolean useIdDirect = mayUseIdDirect( idType );
 
 		// create the collection holding the Orphans
-		Collection res = new ArrayList();
+		final Collection res = new ArrayList();
 
 		// collect EntityIdentifier(s) of the *current* elements - add them into a HashSet for fast access
-		java.util.Set currentIds = new HashSet();
-		java.util.Set currentSaving = new IdentitySet();
+		final java.util.Set currentIds = new HashSet();
+		final java.util.Set currentSaving = new IdentitySet();
 		for ( Object current : currentElements ) {
 			if ( current != null && ForeignKeys.isNotTransient( entityName, current, null, session ) ) {
-				EntityEntry ee = session.getPersistenceContext().getEntry( current );
+				final EntityEntry ee = session.getPersistenceContext().getEntry( current );
 				if ( ee != null && ee.getStatus() == Status.SAVING ) {
 					currentSaving.add( current );
 				}
 				else {
-					Serializable currentId = ForeignKeys.getEntityIdentifierIfNotUnsaved(
+					final Serializable currentId = ForeignKeys.getEntityIdentifierIfNotUnsaved(
 							entityName,
 							current,
 							session
 					);
-					currentIds.add( new TypedValue( idType, currentId, entityPersister.getEntityMode() ) );
+					currentIds.add( useIdDirect ? currentId : new TypedValue( idType, currentId ) );
 				}
 			}
 		}
@@ -1248,8 +1287,8 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
 		// iterate over the *old* list
 		for ( Object old : oldElements ) {
 			if ( !currentSaving.contains( old ) ) {
-				Serializable oldId = ForeignKeys.getEntityIdentifierIfNotUnsaved( entityName, old, session );
-				if ( !currentIds.contains( new TypedValue( idType, oldId, entityPersister.getEntityMode() ) ) ) {
+				final Serializable oldId = ForeignKeys.getEntityIdentifierIfNotUnsaved( entityName, old, session );
+				if ( !currentIds.contains( useIdDirect ? oldId : new TypedValue( idType, oldId ) ) ) {
 					res.add( old );
 				}
 			}
@@ -1258,20 +1297,37 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
 		return res;
 	}
 
+	private static boolean mayUseIdDirect(Type idType) {
+		return idType == StringType.INSTANCE
+			|| idType == IntegerType.INSTANCE
+			|| idType == LongType.INSTANCE
+			|| idType == UUIDBinaryType.INSTANCE
+			|| idType == UUIDCharType.INSTANCE
+			|| idType == PostgresUUIDType.INSTANCE;
+	}
+
+	/**
+	 * Removes entity entries that have an equal identifier with the incoming entity instance
+	 *
+	 * @param list The list containing the entity instances
+	 * @param entityInstance The entity instance to match elements.
+	 * @param entityName The entity name
+	 * @param session The session
+	 */
 	public static void identityRemove(
 			Collection list,
-			Object object,
+			Object entityInstance,
 			String entityName,
-			SessionImplementor session) throws HibernateException {
+			SessionImplementor session) {
 
-		if ( object != null && ForeignKeys.isNotTransient( entityName, object, null, session ) ) {
+		if ( entityInstance != null && ForeignKeys.isNotTransient( entityName, entityInstance, null, session ) ) {
 			final EntityPersister entityPersister = session.getFactory().getEntityPersister( entityName );
-			Type idType = entityPersister.getIdentifierType();
+			final Type idType = entityPersister.getIdentifierType();
 
-			Serializable idOfCurrent = ForeignKeys.getEntityIdentifierIfNotUnsaved( entityName, object, session );
-			Iterator itr = list.iterator();
+			final Serializable idOfCurrent = ForeignKeys.getEntityIdentifierIfNotUnsaved( entityName, entityInstance, session );
+			final Iterator itr = list.iterator();
 			while ( itr.hasNext() ) {
-				Serializable idOfOld = ForeignKeys.getEntityIdentifierIfNotUnsaved( entityName, itr.next(), session );
+				final Serializable idOfOld = ForeignKeys.getEntityIdentifierIfNotUnsaved( entityName, itr.next(), session );
 				if ( idType.isEqual( idOfCurrent, idOfOld, session.getFactory() ) ) {
 					itr.remove();
 					break;
@@ -1282,21 +1338,27 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
 	}
 
 	@Override
-    public Object getIdentifier(Object entry, int i) {
+	public Object getIdentifier(Object entry, int i) {
 		throw new UnsupportedOperationException();
 	}
 
 	@Override
-    public Object getOwner() {
+	public Object getOwner() {
 		return owner;
 	}
 
 	@Override
-    public void setOwner(Object owner) {
+	public void setOwner(Object owner) {
 		this.owner = owner;
 	}
 
-	/** ------ Below is section of code which makes remote service calls ----- */
+/** #################################################################### 
+    
+    ADDED PART: Below is section of code which makes remote service calls 
+    
+    #################################################################### */
+    
+	
 	// The affected methods are :
 	// initialize(final boolean writing)
 	// readSize()
@@ -1320,7 +1382,7 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
 			try {
 				String role = getRole();
 				String fieldName = role.substring(role.lastIndexOf(".") + 1);
-				log.info("--> Remote Lazy Initializing Collection " + getRole() + " , owner : " + getOwner().getClass() + "/" + getKey() + " , field : " + fieldName);
+				LOG.info("--> Remote Lazy Initializing Collection " + getRole() + " , owner : " + getOwner().getClass() + "/" + getKey() + " , field : " + fieldName);
 				Object owner = getOwner();
 				CdmBase cdmBase;
 				if(owner instanceof CdmBase) {
@@ -1359,8 +1421,4 @@ public abstract class AbstractPersistentCollection implements Serializable, Pers
 			}
 		}
 	}
-
-
-
-}
-
+}
\ No newline at end of file
