好东西,hibernate-3.2.0,他是一开元的树杖hibernate-3.2.0

源代码在线查看: collectionentry.java

软件大小: 24233 K
上传用户: sujiwei
关键词: hibernate
下载地址: 免注册下载 普通下载 VIP

相关代码

				//$Id: CollectionEntry.java 9551 2006-03-04 03:49:55Z steve.ebersole@jboss.com $
				package org.hibernate.engine;
				
				import java.io.Serializable;
				import java.io.ObjectOutputStream;
				import java.io.IOException;
				import java.io.ObjectInputStream;
				import java.util.Collection;
				
				import org.apache.commons.logging.Log;
				import org.apache.commons.logging.LogFactory;
				import org.hibernate.AssertionFailure;
				import org.hibernate.HibernateException;
				import org.hibernate.MappingException;
				import org.hibernate.collection.PersistentCollection;
				import org.hibernate.persister.collection.CollectionPersister;
				import org.hibernate.pretty.MessageHelper;
				
				/**
				 * We need an entry to tell us all about the current state
				 * of a collection with respect to its persistent state
				 * 
				 * @author Gavin King
				 */
				public final class CollectionEntry implements Serializable {
				
					private static final Log log = LogFactory.getLog(CollectionEntry.class);
					
					//ATTRIBUTES MAINTAINED BETWEEN FLUSH CYCLES
					
					// session-start/post-flush persistent state
					private Serializable snapshot;
					// allow the CollectionSnapshot to be serialized
					private String role;
					
					// "loaded" means the reference that is consistent 
					// with the current database state
					private transient CollectionPersister loadedPersister;
					private Serializable loadedKey;
				
					// ATTRIBUTES USED ONLY DURING FLUSH CYCLE
					
					// during flush, we navigate the object graph to
					// collections and decide what to do with them
					private transient boolean reached;
					private transient boolean processed;
					private transient boolean doupdate;
					private transient boolean doremove;
					private transient boolean dorecreate;
					// if we instantiate a collection during the flush() process,
					// we must ignore it for the rest of the flush()
					private transient boolean ignore;
					
					// "current" means the reference that was found during flush() 
					private transient CollectionPersister currentPersister;
					private transient Serializable currentKey;
				
					/**
					 * For newly wrapped collections, or dereferenced collection wrappers
					 */
					public CollectionEntry(CollectionPersister persister, PersistentCollection collection) {
						// new collections that get found + wrapped
						// during flush shouldn't be ignored
						ignore = false;
				
						collection.clearDirty(); //a newly wrapped collection is NOT dirty (or we get unnecessary version updates)
						
						snapshot = persister.isMutable() ?
								collection.getSnapshot(persister) :
								null;
						collection.setSnapshot(loadedKey, role, snapshot);
					}
				
					/**
					 * For collections just loaded from the database
					 */
					public CollectionEntry(
							final PersistentCollection collection, 
							final CollectionPersister loadedPersister, 
							final Serializable loadedKey, 
							final boolean ignore
					) {
						this.ignore=ignore;
				
						//collection.clearDirty()
						
						this.loadedKey = loadedKey;
						setLoadedPersister(loadedPersister);
				
						collection.setSnapshot(loadedKey, role, null);
				
						//postInitialize() will be called after initialization
					}
				
					/**
					 * For uninitialized detached collections
					 */
					public CollectionEntry(CollectionPersister loadedPersister, Serializable loadedKey) {
						// detached collection wrappers that get found + reattached
						// during flush shouldn't be ignored
						ignore = false;
				
						//collection.clearDirty()
						
						this.loadedKey = loadedKey;
						setLoadedPersister(loadedPersister);
					}
					
					/**
					 * For initialized detached collections
					 */
					CollectionEntry(PersistentCollection collection, SessionFactoryImplementor factory)
					throws MappingException {
						// detached collections that get found + reattached
						// during flush shouldn't be ignored
						ignore = false;
				
						loadedKey = collection.getKey();
						setLoadedPersister( factory.getCollectionPersister( collection.getRole() ) );
				
						snapshot = collection.getStoredSnapshot();		
					}
				
					/**
					 * Used from custom serialization.
					 *
					 * @see #serialize
					 * @see #deserialize
					 */
					private CollectionEntry(
							String role,
					        Serializable snapshot,
					        Serializable loadedKey,
					        SessionFactoryImplementor factory) {
						this.role = role;
						this.snapshot = snapshot;
						this.loadedKey = loadedKey;
						if ( role != null ) {
							afterDeserialize( factory );
						}
					}
				
					/**
					 * Determine if the collection is "really" dirty, by checking dirtiness
					 * of the collection elements, if necessary
					 */
					private void dirty(PersistentCollection collection) throws HibernateException {
						
						boolean forceDirty = collection.wasInitialized() &&
								!collection.isDirty() && //optimization
								getLoadedPersister() != null &&
								getLoadedPersister().isMutable() && //optimization
								( collection.isDirectlyAccessible() || getLoadedPersister().getElementType().isMutable() ) && //optimization
								!collection.equalsSnapshot( getLoadedPersister() );
						
						if ( forceDirty ) {
							collection.dirty();
						}
						
					}
				
					public void preFlush(PersistentCollection collection) throws HibernateException {
						
						boolean nonMutableChange = collection.isDirty() && 
								getLoadedPersister()!=null && 
								!getLoadedPersister().isMutable();
						if (nonMutableChange) {
							throw new HibernateException(
									"changed an immutable collection instance: " + 
									MessageHelper.collectionInfoString( getLoadedPersister().getRole(), getLoadedKey() )
								);
						}
						
						dirty(collection);
						
						if ( log.isDebugEnabled() && collection.isDirty() && getLoadedPersister() != null ) {
							log.debug(
									"Collection dirty: " +
									MessageHelper.collectionInfoString( getLoadedPersister().getRole(), getLoadedKey() )
								);
						}
				
						setDoupdate(false);
						setDoremove(false);
						setDorecreate(false);
						setReached(false);
						setProcessed(false);
					}
				
					public void postInitialize(PersistentCollection collection) throws HibernateException {
						snapshot = getLoadedPersister().isMutable() ?
								collection.getSnapshot( getLoadedPersister() ) :
								null;
						collection.setSnapshot(loadedKey, role, snapshot);
					}
				
					/**
					 * Called after a successful flush
					 */
					public void postFlush(PersistentCollection collection) throws HibernateException {
						if ( isIgnore() ) {
							ignore = false;
						}
						else if ( !isProcessed() ) {
							throw new AssertionFailure( "collection [" + collection.getRole() + "] was not processed by flush()" );
						}
						collection.setSnapshot(loadedKey, role, snapshot);
					}
					
					/**
					 * Called after execution of an action
					 */
					public void afterAction(PersistentCollection collection) {
						loadedKey = getCurrentKey();
						setLoadedPersister( getCurrentPersister() );
						
						boolean resnapshot = collection.wasInitialized() && 
								( isDoremove() || isDorecreate() || isDoupdate() );
						if ( resnapshot ) {
							snapshot = loadedPersister==null || !loadedPersister.isMutable() ? 
									null : 
									collection.getSnapshot(loadedPersister); //re-snapshot
						}
						
						collection.postAction();
					}
				
					public Serializable getKey() {
						return getLoadedKey();
					}
				
					public String getRole() {
						return role;
					}
				
					public Serializable getSnapshot() {
						return snapshot;
					}
				
					private void setLoadedPersister(CollectionPersister persister) {
						loadedPersister = persister;
						setRole( persister == null ? null : persister.getRole() );
					}
					
					void afterDeserialize(SessionFactoryImplementor factory) {
						loadedPersister = factory.getCollectionPersister(role);
					}
				
					public boolean wasDereferenced() {
						return getLoadedKey() == null;
					}
				
					public boolean isReached() {
						return reached;
					}
				
					public void setReached(boolean reached) {
						this.reached = reached;
					}
				
					public boolean isProcessed() {
						return processed;
					}
				
					public void setProcessed(boolean processed) {
						this.processed = processed;
					}
				
					public boolean isDoupdate() {
						return doupdate;
					}
				
					public void setDoupdate(boolean doupdate) {
						this.doupdate = doupdate;
					}
				
					public boolean isDoremove() {
						return doremove;
					}
				
					public void setDoremove(boolean doremove) {
						this.doremove = doremove;
					}
				
					public boolean isDorecreate() {
						return dorecreate;
					}
				
					public void setDorecreate(boolean dorecreate) {
						this.dorecreate = dorecreate;
					}
				
					public boolean isIgnore() {
						return ignore;
					}
				
					public CollectionPersister getCurrentPersister() {
						return currentPersister;
					}
				
					public void setCurrentPersister(CollectionPersister currentPersister) {
						this.currentPersister = currentPersister;
					}
				
					/**
					 * This is only available late during the flush
					 * cycle
					 */
					public Serializable getCurrentKey() {
						return currentKey;
					}
				
					public void setCurrentKey(Serializable currentKey) {
						this.currentKey = currentKey;
					}
					
					/**
					 * This is only available late during the flush cycle
					 */
					public CollectionPersister getLoadedPersister() {
						return loadedPersister;
					}
				
					public Serializable getLoadedKey() {
						return loadedKey;
					}
				
					public void setRole(String role) {
						this.role = role;
					}
				
					public String toString() {
						String result = "CollectionEntry" + 
								MessageHelper.collectionInfoString( loadedPersister.getRole(), loadedKey );
						if (currentPersister!=null) {
							result += "->" + 
									MessageHelper.collectionInfoString( currentPersister.getRole(), currentKey );
						}
						return result;
					}
				
					/**
					 * Get the collection orphans (entities which were removed from the collection)
					 */
					public Collection getOrphans(String entityName, PersistentCollection collection) 
					throws HibernateException {
						if (snapshot==null) {
							throw new AssertionFailure("no collection snapshot for orphan delete");
						}
						return collection.getOrphans( snapshot, entityName );
					}
				
					public boolean isSnapshotEmpty(PersistentCollection collection) {
						//TODO: does this really need to be here?
						//      does the collection already have
						//      it's own up-to-date snapshot?
						return collection.wasInitialized() && 
							( getLoadedPersister()==null || getLoadedPersister().isMutable() ) &&
							collection.isSnapshotEmpty( getSnapshot() );
					}
				
				
				
					/**
					 * Custom serialization routine used during serialization of a
					 * Session/PersistenceContext for increased performance.
					 *
					 * @param oos The stream to which we should write the serial data.
					 * @throws java.io.IOException
					 */
					void serialize(ObjectOutputStream oos) throws IOException {
						oos.writeObject( role );
						oos.writeObject( snapshot );
						oos.writeObject( loadedKey );
					}
				
					/**
					 * Custom deserialization routine used during deserialization of a
					 * Session/PersistenceContext for increased performance.
					 *
					 * @param ois The stream from which to read the entry.
					 * @param session The session being deserialized.
					 * @return The deserialized CollectionEntry
					 * @throws IOException
					 * @throws ClassNotFoundException
					 */
					static CollectionEntry deserialize(
							ObjectInputStream ois,
					        SessionImplementor session) throws IOException, ClassNotFoundException {
						return new CollectionEntry(
								( String ) ois.readObject(),
						        ( Serializable ) ois.readObject(),
						        ( Serializable ) ois.readObject(),
						        session.getFactory()
						);
					}
				}			

相关资源