📄 abstractpersistentcollection.java
字号:
//$Id: AbstractPersistentCollection.java,v 1.17 2005/04/02 20:33:53 oneovthafew Exp $package org.hibernate.collection;import java.io.Serializable;import java.util.ArrayList;import java.util.Collection;import java.util.HashSet;import java.util.Iterator;import java.util.List;import java.util.ListIterator;import org.hibernate.AssertionFailure;import org.hibernate.HibernateException;import org.hibernate.LazyInitializationException;import org.hibernate.engine.CollectionSnapshot;import org.hibernate.engine.ForeignKeys;import org.hibernate.engine.SessionImplementor;import org.hibernate.engine.TypedValue;import org.hibernate.persister.collection.CollectionPersister;import org.hibernate.type.Type;import org.hibernate.util.EmptyIterator;/** * Base class implementing <tt>PersistentCollection</tt> * @see PersistentCollection * @author Gavin King */public abstract class AbstractPersistentCollection implements Serializable, PersistentCollection { private transient SessionImplementor session; private boolean initialized; private transient List additions; private CollectionSnapshot collectionSnapshot; private transient boolean directlyAccessible; private transient boolean initializing; private Object owner; //Careful: these methods do not initialize the collection. /** * Is the initialized collection empty? */ public abstract boolean empty(); /** * Called by any read-only method of the collection interface */ protected final void read() { initialize(false); } /** * Is the collection currently connected to an open session? */ private final boolean isConnectedToSession() { return session!=null && session.isOpen(); } /** * Called by any writer method of the collection interface */ protected final void write() { initialize(true); collectionSnapshot.setDirty(); } /** * Is this collection in a state that would allow us to * "queue" additions? */ private boolean isQueueAdditionEnabled() { return !initialized && isConnectedToSession() && session.getPersistenceContext().isInverseCollection(this); } /** * Queue an addition */ protected final boolean queueAdd(Object element) { if ( isQueueAdditionEnabled() ) { if (additions==null) additions = new ArrayList(10); additions.add(element); collectionSnapshot.setDirty(); //needed so that we remove this collection from the second-level cache return true; } else { return false; } } /** * Queue additions */ protected final boolean queueAddAll(Collection coll) { if ( isQueueAdditionEnabled() ) { if (additions==null) additions = new ArrayList(20); additions.addAll(coll); return true; } else { return false; } } /** * After reading all existing elements from the database, * add the queued elements to the underlying collection. */ public void delayedAddAll(Collection coll) { throw new AssertionFailure("Collection does not support delayed initialization"); } /** * After flushing, clear any "queued" additions, since the * database state is now synchronized with the memory state. */ public void postFlush() { if (additions!=null) additions=null; } /** * 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 */ public Object getValue() { return this; } /** * Called just before reading any rows from the JDBC result set */ public void beginRead() { // override on some subclasses initializing = true; } /** * Called after reading all rows from the JDBC result set */ public boolean endRead() { //override on some subclasses setInitialized(); //do this bit after setting initialized to true or it will recurse if (additions!=null) { delayedAddAll(additions); additions=null; return false; } else { return true; } } /** * Initialize the collection, if possible, wrapping any exceptions * in a runtime exception * @param writing currently obsolete * @throws LazyInitializationException if we cannot initialize */ protected final void initialize(boolean writing) { if (!initialized) { if (initializing) throw new LazyInitializationException("cannot access loading collection"); if ( isConnectedToSession() ) { if ( session.isConnected() ) { session.initializeCollection(this, writing); } else { String name = (getCollectionSnapshot()!=null)?"("+getCollectionSnapshot().getRole()+")":""; throw new LazyInitializationException("failed to lazily initialize a collection " + name + " - session is disconnected"); } } else { String name = (getCollectionSnapshot()!=null)?"("+getCollectionSnapshot().getRole()+")":""; throw new LazyInitializationException("failed to lazily initialize a collection " + name + " - no session or session was closed"); } } } protected final void setInitialized() { this.initializing = false; this.initialized = true; } protected final void setDirectlyAccessible(boolean directlyAccessible) { this.directlyAccessible = directlyAccessible; } /** * Could the application possibly have a direct reference to * the underlying collection implementation? */ public boolean isDirectlyAccessible() { return directlyAccessible; } /** * Disassociate this collection from the given session. * @return true if this was currently associated with the given session */ public final boolean unsetSession(SessionImplementor currentSession) { if (currentSession==this.session) { this.session=null; return true; } else { return false; } } /** * 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 */ public final boolean setCurrentSession(SessionImplementor session) throws HibernateException { if (session==this.session) { return false; } else { if ( isConnectedToSession() ) { throw new HibernateException("Illegal attempt to associate a collection with two open sessions"); } else { this.session = session; return true; } } } /** * Do we need to completely recreate this collection when it changes? */ public boolean needsRecreate(CollectionPersister persister) { return false; } /** * Return a new snapshot of the current state of the collection, * or null if no persister is passed */ public final Serializable getSnapshot(CollectionPersister persister) throws HibernateException { return (persister==null) ? null : snapshot(persister); } /** * Return a new snapshot of the current state */ protected abstract Serializable snapshot(CollectionPersister persister) throws HibernateException; /** * To be called internally by the session, forcing * immediate initialization. */ 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); } } /** * Get the current snapshot from the session */ protected final Serializable getSnapshot() { return session.getPersistenceContext().getSnapshot(this); } /** * Is this instance initialized? */ public final boolean wasInitialized() { return initialized; } public boolean isRowUpdatePossible() { return true; } /** * Does this instance have any "queued" additions? */ public final boolean hasQueuedAdditions() { return additions!=null; } /** * Iterate the "queued" additions */ public final Iterator queuedAdditionIterator() { return hasQueuedAdditions() ? additions.iterator() : EmptyIterator.INSTANCE; } /** * Returns the collectionSnapshot. * @return CollectionSnapshot */ public CollectionSnapshot getCollectionSnapshot() { return collectionSnapshot; } /** * Sets the collectionSnapshot. * @param collectionSnapshot The collectionSnapshot to set */ public void setCollectionSnapshot(CollectionSnapshot collectionSnapshot) { this.collectionSnapshot = collectionSnapshot; } /** * Called before inserting rows, to ensure that any surrogate keys * are fully generated */ public void preInsert(CollectionPersister persister) throws HibernateException {} /** * Called after inserting a row, to fetch the natively generated id */ public void afterRowInsert(CollectionPersister persister, Object entry, int i) throws HibernateException {} /** * get all "orphaned" elements * @param entityName TODO */ public abstract Collection getOrphans(Serializable snapshot, String entityName) throws HibernateException; /** * Get the current session */ protected final SessionImplementor getSession() { return session; } final class IteratorProxy implements Iterator { private final Iterator iter; IteratorProxy(Iterator iter) { this.iter=iter; } public boolean hasNext() { return iter.hasNext(); } public Object next() { return iter.next(); } public void remove() { write(); iter.remove(); } } final class ListIteratorProxy implements ListIterator {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -