⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 abstractpersistentcollection.java

📁 一个Java持久层类库
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
//$Id: AbstractPersistentCollection.java 11302 2007-03-19 20:44:11Z steve.ebersole@jboss.com $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.CollectionEntry;import org.hibernate.engine.ForeignKeys;import org.hibernate.engine.SessionImplementor;import org.hibernate.engine.TypedValue;import org.hibernate.persister.collection.CollectionPersister;import org.hibernate.pretty.MessageHelper;import org.hibernate.type.Type;import org.hibernate.util.CollectionHelper;import org.hibernate.util.EmptyIterator;import org.hibernate.util.MarkerObject;/** * 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 operationQueue;	private transient boolean directlyAccessible;	private transient boolean initializing;	private Object owner;	private int cachedSize = -1;		private String role;	private Serializable key;	// collections detect changes made via their public interface and mark	// themselves as dirty as a performance optimization	private boolean dirty;	private Serializable storedSnapshot;	public final String getRole() {		return role;	}		public final Serializable getKey() {		return key;	}		public final boolean isUnreferenced() {		return role==null;	}		public final boolean isDirty() {		return dirty;	}		public final void clearDirty() {		dirty = false;	}		public final void dirty() {		dirty = true;	}		public final Serializable getStoredSnapshot() {		return storedSnapshot;	}		//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);	}	/**	 * Called by the <tt>size()</tt> method	 */	protected boolean readSize() {		if (!initialized) {			if ( cachedSize!=-1 && !hasQueuedOperations() ) {				return true;			}			else {				throwLazyInitializationExceptionIfNotConnected();				CollectionEntry entry = session.getPersistenceContext().getCollectionEntry(this);				CollectionPersister persister = entry.getLoadedPersister();				if ( persister.isExtraLazy() ) {					if ( hasQueuedOperations() ) {						session.flush();					}					cachedSize = persister.getSize( entry.getLoadedKey(), session );					return true;				}			}		}		read();		return false;	}		protected Boolean readIndexExistence(Object index) {		if (!initialized) {			throwLazyInitializationExceptionIfNotConnected();			CollectionEntry entry = session.getPersistenceContext().getCollectionEntry(this);			CollectionPersister persister = entry.getLoadedPersister();			if ( persister.isExtraLazy() ) {				if ( hasQueuedOperations() ) {					session.flush();				}				return new Boolean( persister.indexExists( entry.getLoadedKey(), index, session ) );			}		}		read();		return null;			}		protected Boolean readElementExistence(Object element) {		if (!initialized) {			throwLazyInitializationExceptionIfNotConnected();			CollectionEntry entry = session.getPersistenceContext().getCollectionEntry(this);			CollectionPersister persister = entry.getLoadedPersister();			if ( persister.isExtraLazy() ) {				if ( hasQueuedOperations() ) {					session.flush();				}				return new Boolean( persister.elementExists( entry.getLoadedKey(), element, session ) );			}		}		read();		return null;			}		protected static final Object UNKNOWN = new MarkerObject("UNKNOWN");		protected Object readElementByIndex(Object index) {		if (!initialized) {			throwLazyInitializationExceptionIfNotConnected();			CollectionEntry entry = session.getPersistenceContext().getCollectionEntry(this);			CollectionPersister persister = entry.getLoadedPersister();			if ( persister.isExtraLazy() ) {				if ( hasQueuedOperations() ) {					session.flush();				}				return persister.getElementByIndex( entry.getLoadedKey(), index, session, owner );			}		}		read();		return UNKNOWN;			}		protected int getCachedSize() {		return cachedSize;	}		/**	 * Is the collection currently connected to an open session?	 */	private final boolean isConnectedToSession() {		return session!=null && 				session.isOpen() &&				session.getPersistenceContext().containsCollection(this);	}	/**	 * Called by any writer method of the collection interface	 */	protected final void write() {		initialize(true);		dirty();	}	/**	 * Is this collection in a state that would allow us to	 * "queue" operations?	 */	protected boolean isOperationQueueEnabled() {		return !initialized &&				isConnectedToSession() &&				isInverseCollection();	}	/**	 * Is this collection in a state that would allow us to	 * "queue" puts? This is a special case, because of orphan	 * delete.	 */	protected boolean isPutQueueEnabled() {		return !initialized &&				isConnectedToSession() &&				isInverseOneToManyOrNoOrphanDelete();	}	/**	 * Is this collection in a state that would allow us to	 * "queue" clear? This is a special case, because of orphan	 * delete.	 */	protected boolean isClearQueueEnabled() {		return !initialized &&				isConnectedToSession() &&				isInverseCollectionNoOrphanDelete();	}	/**	 * Is this the "inverse" end of a bidirectional association?	 */	private boolean isInverseCollection() {		CollectionEntry ce = session.getPersistenceContext().getCollectionEntry(this);		return ce != null && ce.getLoadedPersister().isInverse();	}	/**	 * Is this the "inverse" end of a bidirectional association with	 * no orphan delete enabled?	 */	private boolean isInverseCollectionNoOrphanDelete() {		CollectionEntry ce = session.getPersistenceContext().getCollectionEntry(this);		return ce != null && 				ce.getLoadedPersister().isInverse() &&				!ce.getLoadedPersister().hasOrphanDelete();	}	/**	 * Is this the "inverse" end of a bidirectional one-to-many, or 	 * of a collection with no orphan delete?	 */	private boolean isInverseOneToManyOrNoOrphanDelete() {		CollectionEntry ce = session.getPersistenceContext().getCollectionEntry(this);		return ce != null && ce.getLoadedPersister().isInverse() && (				ce.getLoadedPersister().isOneToMany() || 				!ce.getLoadedPersister().hasOrphanDelete() 			);	}	/**	 * Queue an addition	 */	protected final void queueOperation(Object element) {		if (operationQueue==null) operationQueue = new ArrayList(10);		operationQueue.add(element);		dirty = true; //needed so that we remove this collection from the second-level cache	}	/**	 * After reading all existing elements from the database,	 * add the queued elements to the underlying collection.	 */	protected final void performQueuedOperations() {		for ( int i=0; i<operationQueue.size(); i++ ) {			( (DelayedOperation) operationQueue.get(i) ).operate();		}	}	/**	 * After flushing, re-init snapshot state.	 */	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.	 */	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	 */	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		return afterInitialize();	}		public boolean afterInitialize() {		setInitialized();		//do this bit after setting initialized to true or it will recurse		if (operationQueue!=null) {			performQueuedOperations();			operationQueue=null;			cachedSize = -1;			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("illegal access to loading collection");			}			throwLazyInitializationExceptionIfNotConnected();			session.initializeCollection(this, writing);		}	}		private void throwLazyInitializationExceptionIfNotConnected() {		if ( !isConnectedToSession() )  {			throwLazyInitializationException("no session or session was closed");		}		if ( !session.isConnected() ) {            throwLazyInitializationException("session is disconnected");		}			}		private void throwLazyInitializationException(String message) {		throw new LazyInitializationException(				"failed to lazily initialize a collection" + 				( role==null ?  "" : " of role: " + role ) + 				", " + message			);	}	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() ) {				CollectionEntry ce = session.getPersistenceContext().getCollectionEntry(this);				if (ce==null) {					throw new HibernateException(							"Illegal attempt to associate a collection with two open sessions"						);				}				else {					throw new HibernateException(							"Illegal attempt to associate a collection with two open sessions: " +							MessageHelper.collectionInfoString( 									ce.getLoadedPersister(), 									ce.getLoadedKey(), 									session.getFactory() 								)						);				}			}			else {				this.session = session;				return true;			}		}	}	/**	 * Do we need to completely recreate this collection when it changes?	 */	public boolean needsRecreate(CollectionPersister persister) {		return false;	}		/**	 * 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;	}	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -