FileDocCategorySizeDatePackage
SessionImpl.javaAPI DocHibernate 3.2.562860Thu Nov 02 11:53:54 GMT 2006org.hibernate.impl

SessionImpl

public final class SessionImpl extends AbstractSessionImpl implements org.hibernate.event.EventSource, org.hibernate.classic.Session, JDBCContext.Context
Concrete implementation of a Session, and also the central, organizing component of Hibernate's internal implementation. As such, this class exposes two interfaces; Session itself, to the application, and SessionImplementor, to other components of Hibernate. This class is not threadsafe.
author
Gavin King

Fields Summary
private static final Log
log
private transient org.hibernate.EntityMode
entityMode
private transient boolean
autoClear
private transient long
timestamp
private transient org.hibernate.FlushMode
flushMode
private transient org.hibernate.CacheMode
cacheMode
private transient org.hibernate.Interceptor
interceptor
private transient int
dontFlushFromFind
private transient org.hibernate.engine.ActionQueue
actionQueue
private transient org.hibernate.engine.StatefulPersistenceContext
persistenceContext
private transient org.hibernate.jdbc.JDBCContext
jdbcContext
private transient org.hibernate.event.EventListeners
listeners
private transient boolean
flushBeforeCompletionEnabled
private transient boolean
autoCloseSessionEnabled
private transient org.hibernate.ConnectionReleaseMode
connectionReleaseMode
private transient String
fetchProfile
private transient Map
enabledFilters
private transient org.hibernate.Session
rootSession
private transient Map
childSessionsByEntityMode
Constructors Summary
private SessionImpl(SessionImpl parent, org.hibernate.EntityMode entityMode)
Constructor used in building "child sessions".

param
parent The parent session
param
entityMode


	             	 
	     
		super( parent.factory );
		this.rootSession = parent;
		this.timestamp = parent.timestamp;
		this.jdbcContext = parent.jdbcContext;
		this.interceptor = parent.interceptor;
		this.listeners = parent.listeners;
		this.actionQueue = new ActionQueue( this );
		this.entityMode = entityMode;
		this.persistenceContext = new StatefulPersistenceContext( this );
		this.flushBeforeCompletionEnabled = false;
		this.autoCloseSessionEnabled = false;
		this.connectionReleaseMode = null;

		if ( factory.getStatistics().isStatisticsEnabled() ) {
			factory.getStatisticsImplementor().openSession();
		}

		log.debug( "opened session [" + entityMode + "]" );
	
SessionImpl(Connection connection, SessionFactoryImpl factory, boolean autoclose, long timestamp, org.hibernate.Interceptor interceptor, org.hibernate.EntityMode entityMode, boolean flushBeforeCompletionEnabled, boolean autoCloseSessionEnabled, org.hibernate.ConnectionReleaseMode connectionReleaseMode)
Constructor used for openSession(...) processing, as well as construction of sessions for getCurrentSession().

param
connection The user-supplied connection to use for this session.
param
factory The factory from which this session was obtained
param
autoclose NOT USED
param
timestamp The timestamp for this session
param
interceptor The interceptor to be applied to this session
param
entityMode The entity-mode for this session
param
flushBeforeCompletionEnabled Should we auto flush before completion of transaction
param
autoCloseSessionEnabled Should we auto close after completion of transaction
param
connectionReleaseMode The mode by which we should release JDBC connections.

		super( factory );
		this.rootSession = null;
		this.timestamp = timestamp;
		this.entityMode = entityMode;
		this.interceptor = interceptor;
		this.listeners = factory.getEventListeners();
		this.actionQueue = new ActionQueue( this );
		this.persistenceContext = new StatefulPersistenceContext( this );
		this.flushBeforeCompletionEnabled = flushBeforeCompletionEnabled;
		this.autoCloseSessionEnabled = autoCloseSessionEnabled;
		this.connectionReleaseMode = connectionReleaseMode;
		this.jdbcContext = new JDBCContext( this, connection, interceptor );

		if ( factory.getStatistics().isStatisticsEnabled() ) {
			factory.getStatisticsImplementor().openSession();
		}

		if ( log.isDebugEnabled() ) {
			log.debug( "opened session at timestamp: " + timestamp );
		}
	
Methods Summary
public voidafterOperation(boolean success)
Check if there is a Hibernate or JTA transaction in progress and, if there is not, flush if necessary, make sure the connection has been committed (if it is not in autocommit mode) and run the after completion processing

		if ( !jdbcContext.isTransactionInProgress() ) {
			jdbcContext.afterNontransactionalQuery( success );
		}
	
public voidafterScrollOperation()

		// nothing to do in a stateful session
	
public voidafterTransactionBegin(org.hibernate.Transaction tx)

		errorIfClosed();
		interceptor.afterTransactionBegin(tx);
	
public voidafterTransactionCompletion(boolean success, org.hibernate.Transaction tx)

		log.trace( "after transaction completion" );
		persistenceContext.afterTransactionCompletion();
		actionQueue.afterTransactionCompletion(success);
		if ( rootSession == null && tx != null ) {
			try {
				interceptor.afterTransactionCompletion(tx);
			}
			catch (Throwable t) {
				log.error("exception in interceptor afterTransactionCompletion()", t);
			}
		}
		if ( autoClear ) {
			clear();
		}
	
protected booleanautoFlushIfRequired(java.util.Set querySpaces)
detect in-memory changes, determine if the changes are to tables named in the query and, if so, complete execution the flush

		errorIfClosed();
		if ( ! isTransactionInProgress() ) {
			// do not auto-flush while outside a transaction
			return false;
		}
		AutoFlushEvent event = new AutoFlushEvent(querySpaces, this);
		AutoFlushEventListener[] autoFlushEventListener = listeners.getAutoFlushEventListeners();
		for ( int i = 0; i < autoFlushEventListener.length; i++ ) {
			autoFlushEventListener[i].onAutoFlush(event);
		}
		return event.isFlushRequired();
	
public voidbeforeTransactionCompletion(org.hibernate.Transaction tx)

		log.trace( "before transaction completion" );
		if ( rootSession == null ) {
			try {
				interceptor.beforeTransactionCompletion(tx);
			}
			catch (Throwable t) {
				log.error("exception in interceptor beforeTransactionCompletion()", t);
			}
		}
	
public org.hibernate.TransactionbeginTransaction()

		errorIfClosed();
		if ( rootSession != null ) {
			// todo : should seriously consider not allowing a txn to begin from a child session
			//      can always route the request to the root session...
			log.warn( "Transaction started on non-root session" );
		}
		Transaction result = getTransaction();
		result.begin();
		return result;
	
public java.lang.StringbestGuessEntityName(java.lang.Object object)

		if (object instanceof HibernateProxy) {
			LazyInitializer initializer = ( ( HibernateProxy ) object ).getHibernateLazyInitializer();
			// it is possible for this method to be called during flush processing,
			// so make certain that we do not accidently initialize an uninitialized proxy
			if ( initializer.isUninitialized() ) {
				return initializer.getEntityName();
			}
			object = initializer.getImplementation();
		}
		EntityEntry entry = persistenceContext.getEntry(object);
		if (entry==null) {
			return guessEntityName(object);
		}
		else {
			return entry.getPersister().getEntityName();
		}
	
public voidcancelQuery()

		errorIfClosed();
		getBatcher().cancelLastQuery();
	
private voidcheckTransactionSynchStatus()

		if ( jdbcContext != null && !isClosed() ) {
			jdbcContext.registerSynchronizationIfPossible();
		}
	
private voidcleanup()
clear all the internal collections, just to help the garbage collector, does not clear anything that is needed during the afterTransactionCompletion() phase

		persistenceContext.clear();
	
public voidclear()

		errorIfClosed();
		checkTransactionSynchStatus();
		persistenceContext.clear();
		actionQueue.clear();
	
public java.sql.Connectionclose()

		log.trace( "closing session" );
		if ( isClosed() ) {
			throw new SessionException( "Session was already closed" );
		}
		

		if ( factory.getStatistics().isStatisticsEnabled() ) {
			factory.getStatisticsImplementor().closeSession();
		}

		try {
			try {
				if ( childSessionsByEntityMode != null ) {
					Iterator childSessions = childSessionsByEntityMode.values().iterator();
					while ( childSessions.hasNext() ) {
						final SessionImpl child = ( SessionImpl ) childSessions.next();
						child.close();
					}
				}
			}
			catch( Throwable t ) {
				// just ignore
			}

			if ( rootSession == null ) {
				return jdbcContext.getConnectionManager().close();
			}
			else {
				return null;
			}
		}
		finally {
			setClosed();
			cleanup();
		}
	
public java.sql.Connectionconnection()

		errorIfClosed();
		return jdbcContext.borrowConnection();
	
public booleancontains(java.lang.Object object)

		errorIfClosed();
		checkTransactionSynchStatus();
		if ( object instanceof HibernateProxy ) {
			//do not use proxiesByKey, since not all
			//proxies that point to this session's
			//instances are in that collection!
			LazyInitializer li = ( (HibernateProxy) object ).getHibernateLazyInitializer();
			if ( li.isUninitialized() ) {
				//if it is an uninitialized proxy, pointing
				//with this session, then when it is accessed,
				//the underlying instance will be "contained"
				return li.getSession()==this;
			}
			else {
				//if it is initialized, see if the underlying
				//instance is contained, since we need to 
				//account for the fact that it might have been
				//evicted
				object = li.getImplementation();
			}
		}
		// A session is considered to contain an entity only if the entity has
		// an entry in the session's persistence context and the entry reports
		// that the entity has not been removed
		EntityEntry entry = persistenceContext.getEntry( object );
		return entry != null && entry.getStatus() != Status.DELETED && entry.getStatus() != Status.GONE;
	
public org.hibernate.CriteriacreateCriteria(java.lang.Class persistentClass, java.lang.String alias)

		errorIfClosed();
		checkTransactionSynchStatus();
		return new CriteriaImpl( persistentClass.getName(), alias, this );
	
public org.hibernate.CriteriacreateCriteria(java.lang.String entityName, java.lang.String alias)

		errorIfClosed();
		checkTransactionSynchStatus();
		return new CriteriaImpl(entityName, alias, this);
	
public org.hibernate.CriteriacreateCriteria(java.lang.Class persistentClass)

		errorIfClosed();
		checkTransactionSynchStatus();
		return new CriteriaImpl( persistentClass.getName(), this );
	
public org.hibernate.CriteriacreateCriteria(java.lang.String entityName)

		errorIfClosed();
		checkTransactionSynchStatus();
		return new CriteriaImpl(entityName, this);
	
public org.hibernate.QuerycreateFilter(java.lang.Object collection, java.lang.String queryString)

		errorIfClosed();
		checkTransactionSynchStatus();
		CollectionFilterImpl filter = new CollectionFilterImpl(
				queryString,
		        collection,
		        this,
		        getFilterQueryPlan( collection, queryString, null, false ).getParameterMetadata()
		);
		filter.setComment( queryString );
		return filter;
	
public org.hibernate.QuerycreateQuery(java.lang.String queryString)

		errorIfClosed();
		checkTransactionSynchStatus();
		return super.createQuery(queryString);
	
public org.hibernate.SQLQuerycreateSQLQuery(java.lang.String sql)

		errorIfClosed();
		checkTransactionSynchStatus();
		return super.createSQLQuery(sql);
	
public org.hibernate.QuerycreateSQLQuery(java.lang.String sql, java.lang.String returnAlias, java.lang.Class returnClass)

		errorIfClosed();
		checkTransactionSynchStatus();
		return new SQLQueryImpl(
				sql,
		        new String[] { returnAlias },
		        new Class[] { returnClass },
		        this,
		        factory.getQueryPlanCache().getSQLParameterMetadata( sql )
		);
	
public org.hibernate.QuerycreateSQLQuery(java.lang.String sql, java.lang.String[] returnAliases, java.lang.Class[] returnClasses)

		errorIfClosed();
		checkTransactionSynchStatus();
		return new SQLQueryImpl(
				sql,
		        returnAliases,
		        returnClasses,
		        this,
		        factory.getQueryPlanCache().getSQLParameterMetadata( sql )
		);
	
public intdelete(java.lang.String query)

		return delete( query, ArrayHelper.EMPTY_OBJECT_ARRAY, ArrayHelper.EMPTY_TYPE_ARRAY );
	
public intdelete(java.lang.String query, java.lang.Object value, org.hibernate.type.Type type)

		return delete( query, new Object[]{value}, new Type[]{type} );
	
public intdelete(java.lang.String query, java.lang.Object[] values, org.hibernate.type.Type[] types)

		errorIfClosed();
		checkTransactionSynchStatus();
		if ( query == null ) {
			throw new IllegalArgumentException("attempt to perform delete-by-query with null query");
		}

		if ( log.isTraceEnabled() ) {
			log.trace( "delete: " + query );
			if ( values.length != 0 ) {
				log.trace( "parameters: " + StringHelper.toString( values ) );
			}
		}

		List list = find( query, values, types );
		int deletionCount = list.size();
		for ( int i = 0; i < deletionCount; i++ ) {
			delete( list.get( i ) );
		}

		return deletionCount;
	
public voiddelete(java.lang.Object object)
Delete a persistent object

		fireDelete( new DeleteEvent(object, this) );
	
public voiddelete(java.lang.String entityName, java.lang.Object object)
Delete a persistent object (by explicit entity name)

		fireDelete( new DeleteEvent( entityName, object, this ) );
	
public voiddelete(java.lang.String entityName, java.lang.Object object, boolean isCascadeDeleteEnabled, java.util.Set transientEntities)
Delete a persistent object

		fireDelete( new DeleteEvent( entityName, object, isCascadeDeleteEnabled, this ), transientEntities );
	
public voiddisableFilter(java.lang.String filterName)

		errorIfClosed();
		checkTransactionSynchStatus();
		enabledFilters.remove(filterName);
	
public java.sql.Connectiondisconnect()

		errorIfClosed();
		log.debug( "disconnecting session" );
		return jdbcContext.getConnectionManager().manualDisconnect();
	
public org.hibernate.FilterenableFilter(java.lang.String filterName)

		errorIfClosed();
		checkTransactionSynchStatus();
		FilterImpl filter = new FilterImpl( factory.getFilterDefinition(filterName) );
		enabledFilters.put(filterName, filter);
		return filter;
	
public voidevict(java.lang.Object object)
remove any hard references to the entity that are held by the infrastructure (references held by application or other persistant instances are okay)

		fireEvict( new EvictEvent(object, this) );
	
public intexecuteNativeUpdate(org.hibernate.engine.query.sql.NativeSQLQuerySpecification nativeQuerySpecification, org.hibernate.engine.QueryParameters queryParameters)

        errorIfClosed();
        checkTransactionSynchStatus();
        queryParameters.validateParameters();
        NativeSQLQueryPlan plan = getNativeSQLQueryPlan(nativeQuerySpecification);

        
        autoFlushIfRequired( plan.getCustomQuery().getQuerySpaces() );
        
        boolean success = false;
        int result = 0;
        try {
            result = plan.performExecuteUpdate(queryParameters, this);
            success = true;
        } finally {
            afterOperation(success);
        }
        return result;
    
public intexecuteUpdate(java.lang.String query, org.hibernate.engine.QueryParameters queryParameters)

		errorIfClosed();
		checkTransactionSynchStatus();
		queryParameters.validateParameters();
		HQLQueryPlan plan = getHQLQueryPlan( query, false );
		autoFlushIfRequired( plan.getQuerySpaces() );

		boolean success = false;
		int result = 0;
		try {
			result = plan.performExecuteUpdate( queryParameters, this );
			success = true;
		}
		finally {
			afterOperation(success);
		}
		return result;
	
public java.util.Collectionfilter(java.lang.Object collection, java.lang.String filter)

		return listFilter( collection, filter, new QueryParameters( new Type[1], new Object[1] ) );
	
public java.util.Collectionfilter(java.lang.Object collection, java.lang.String filter, java.lang.Object value, org.hibernate.type.Type type)

		return listFilter( collection, filter, new QueryParameters( new Type[]{null, type}, new Object[]{null, value} ) );
	
public java.util.Collectionfilter(java.lang.Object collection, java.lang.String filter, java.lang.Object[] values, org.hibernate.type.Type[] types)

		Object[] vals = new Object[values.length + 1];
		Type[] typs = new Type[types.length + 1];
		System.arraycopy( values, 0, vals, 1, values.length );
		System.arraycopy( types, 0, typs, 1, types.length );
		return listFilter( collection, filter, new QueryParameters( typs, vals ) );
	
public java.util.Listfind(java.lang.String query)
Retrieve a list of persistent objects using a hibernate query

		return list( query, new QueryParameters() );
	
public java.util.Listfind(java.lang.String query, java.lang.Object value, org.hibernate.type.Type type)

		return list( query, new QueryParameters(type, value) );
	
public java.util.Listfind(java.lang.String query, java.lang.Object[] values, org.hibernate.type.Type[] types)

		return list( query, new QueryParameters(types, values) );
	
private voidfireDelete(org.hibernate.event.DeleteEvent event)

		errorIfClosed();
		checkTransactionSynchStatus();
		DeleteEventListener[] deleteEventListener = listeners.getDeleteEventListeners();
		for ( int i = 0; i < deleteEventListener.length; i++ ) {
			deleteEventListener[i].onDelete( event );
		}
	
private voidfireDelete(org.hibernate.event.DeleteEvent event, java.util.Set transientEntities)

		errorIfClosed();
		checkTransactionSynchStatus();
		DeleteEventListener[] deleteEventListener = listeners.getDeleteEventListeners();
		for ( int i = 0; i < deleteEventListener.length; i++ ) {
			deleteEventListener[i].onDelete( event, transientEntities );
		}
	
private voidfireEvict(org.hibernate.event.EvictEvent evictEvent)

		errorIfClosed();
		checkTransactionSynchStatus();
		EvictEventListener[] evictEventListener = listeners.getEvictEventListeners();
		for ( int i = 0; i < evictEventListener.length; i++ ) {
			evictEventListener[i].onEvict( evictEvent );
		}
	
private voidfireLoad(org.hibernate.event.LoadEvent event, org.hibernate.event.LoadEventListener.LoadType loadType)

		errorIfClosed();
		checkTransactionSynchStatus();
		LoadEventListener[] loadEventListener = listeners.getLoadEventListeners();
		for ( int i = 0; i < loadEventListener.length; i++ ) {
			loadEventListener[i].onLoad(event, loadType);
		}
	
private voidfireLock(org.hibernate.event.LockEvent lockEvent)

		errorIfClosed();
		checkTransactionSynchStatus();
		LockEventListener[] lockEventListener = listeners.getLockEventListeners();
		for ( int i = 0; i < lockEventListener.length; i++ ) {
			lockEventListener[i].onLock( lockEvent );
		}
	
private java.lang.ObjectfireMerge(org.hibernate.event.MergeEvent event)

		errorIfClosed();
		checkTransactionSynchStatus();
		MergeEventListener[] mergeEventListener = listeners.getMergeEventListeners();
		for ( int i = 0; i < mergeEventListener.length; i++ ) {
			mergeEventListener[i].onMerge(event);
		}
		return event.getResult();
	
private voidfireMerge(java.util.Map copiedAlready, org.hibernate.event.MergeEvent event)

		errorIfClosed();
		checkTransactionSynchStatus();
		MergeEventListener[] mergeEventListener = listeners.getMergeEventListeners();
		for ( int i = 0; i < mergeEventListener.length; i++ ) {
			mergeEventListener[i].onMerge(event, copiedAlready);
		}
	
private voidfirePersist(java.util.Map copiedAlready, org.hibernate.event.PersistEvent event)

		errorIfClosed();
		checkTransactionSynchStatus();
		PersistEventListener[] persistEventListener = listeners.getPersistEventListeners();
		for ( int i = 0; i < persistEventListener.length; i++ ) {
			persistEventListener[i].onPersist(event, copiedAlready);
		}
	
private voidfirePersist(org.hibernate.event.PersistEvent event)

		errorIfClosed();
		checkTransactionSynchStatus();
		PersistEventListener[] createEventListener = listeners.getPersistEventListeners();
		for ( int i = 0; i < createEventListener.length; i++ ) {
			createEventListener[i].onPersist(event);
		}
	
private voidfirePersistOnFlush(java.util.Map copiedAlready, org.hibernate.event.PersistEvent event)

		errorIfClosed();
		checkTransactionSynchStatus();
		PersistEventListener[] persistEventListener = listeners.getPersistOnFlushEventListeners();
		for ( int i = 0; i < persistEventListener.length; i++ ) {
			persistEventListener[i].onPersist(event, copiedAlready);
		}
	
private voidfirePersistOnFlush(org.hibernate.event.PersistEvent event)

		errorIfClosed();
		checkTransactionSynchStatus();
		PersistEventListener[] createEventListener = listeners.getPersistOnFlushEventListeners();
		for ( int i = 0; i < createEventListener.length; i++ ) {
			createEventListener[i].onPersist(event);
		}
	
private voidfireRefresh(org.hibernate.event.RefreshEvent refreshEvent)

		errorIfClosed();
		checkTransactionSynchStatus();
		RefreshEventListener[] refreshEventListener = listeners.getRefreshEventListeners();
		for ( int i = 0; i < refreshEventListener.length; i++ ) {
			refreshEventListener[i].onRefresh( refreshEvent );
		}
	
private voidfireRefresh(java.util.Map refreshedAlready, org.hibernate.event.RefreshEvent refreshEvent)

		errorIfClosed();
		checkTransactionSynchStatus();
		RefreshEventListener[] refreshEventListener = listeners.getRefreshEventListeners();
		for ( int i = 0; i < refreshEventListener.length; i++ ) {
			refreshEventListener[i].onRefresh( refreshEvent, refreshedAlready );
		}
	
private voidfireReplicate(org.hibernate.event.ReplicateEvent event)

		errorIfClosed();
		checkTransactionSynchStatus();
		ReplicateEventListener[] replicateEventListener = listeners.getReplicateEventListeners();
		for ( int i = 0; i < replicateEventListener.length; i++ ) {
			replicateEventListener[i].onReplicate(event);
		}
	
private java.io.SerializablefireSave(org.hibernate.event.SaveOrUpdateEvent event)

		errorIfClosed();
		checkTransactionSynchStatus();
		SaveOrUpdateEventListener[] saveEventListener = listeners.getSaveEventListeners();
		for ( int i = 0; i < saveEventListener.length; i++ ) {
			saveEventListener[i].onSaveOrUpdate(event);
		}
		return event.getResultId();
	
private voidfireSaveOrUpdate(org.hibernate.event.SaveOrUpdateEvent event)

		errorIfClosed();
		checkTransactionSynchStatus();
		SaveOrUpdateEventListener[] saveOrUpdateEventListener = listeners.getSaveOrUpdateEventListeners();
		for ( int i = 0; i < saveOrUpdateEventListener.length; i++ ) {
			saveOrUpdateEventListener[i].onSaveOrUpdate(event);
		}
	
private voidfireSaveOrUpdateCopy(java.util.Map copiedAlready, org.hibernate.event.MergeEvent event)

		errorIfClosed();
		checkTransactionSynchStatus();
		MergeEventListener[] saveOrUpdateCopyEventListener = listeners.getSaveOrUpdateCopyEventListeners();
		for ( int i = 0; i < saveOrUpdateCopyEventListener.length; i++ ) {
			saveOrUpdateCopyEventListener[i].onMerge(event, copiedAlready);
		}
	
private java.lang.ObjectfireSaveOrUpdateCopy(org.hibernate.event.MergeEvent event)

		errorIfClosed();
		checkTransactionSynchStatus();
		MergeEventListener[] saveOrUpdateCopyEventListener = listeners.getSaveOrUpdateCopyEventListeners();
		for ( int i = 0; i < saveOrUpdateCopyEventListener.length; i++ ) {
			saveOrUpdateCopyEventListener[i].onMerge(event);
		}
		return event.getResult();
	
private voidfireUpdate(org.hibernate.event.SaveOrUpdateEvent event)

		errorIfClosed();
		checkTransactionSynchStatus();
		SaveOrUpdateEventListener[] updateEventListener = listeners.getUpdateEventListeners();
		for ( int i = 0; i < updateEventListener.length; i++ ) {
			updateEventListener[i].onSaveOrUpdate(event);
		}
	
public voidflush()

		errorIfClosed();
		checkTransactionSynchStatus();
		if ( persistenceContext.getCascadeLevel() > 0 ) {
			throw new HibernateException("Flush during cascade is dangerous");
		}
		FlushEventListener[] flushEventListener = listeners.getFlushEventListeners();
		for ( int i = 0; i < flushEventListener.length; i++ ) {
			flushEventListener[i].onFlush( new FlushEvent(this) );
		}
	
public voidforceFlush(org.hibernate.engine.EntityEntry entityEntry)

		errorIfClosed();
		if ( log.isDebugEnabled() ) {
			log.debug(
				"flushing to force deletion of re-saved object: " +
				MessageHelper.infoString( entityEntry.getPersister(), entityEntry.getId(), getFactory() )
			);
		}

		if ( persistenceContext.getCascadeLevel() > 0 ) {
			throw new ObjectDeletedException(
				"deleted object would be re-saved by cascade (remove deleted object from associations)",
				entityEntry.getId(),
				entityEntry.getPersister().getEntityName()
			);
		}

		flush();
	
public java.lang.Objectget(java.lang.Class entityClass, java.io.Serializable id)

		return get( entityClass.getName(), id );
	
public java.lang.Objectget(java.lang.String entityName, java.io.Serializable id)

		LoadEvent event = new LoadEvent(id, entityName, false, this);
		boolean success = false;
		try {
			fireLoad(event, LoadEventListener.GET);
			success = true;
			return event.getResult();
		}
		finally {
			afterOperation(success);
		}
	
public java.lang.Objectget(java.lang.Class entityClass, java.io.Serializable id, org.hibernate.LockMode lockMode)

		return get( entityClass.getName(), id, lockMode );
	
public java.lang.Objectget(java.lang.String entityName, java.io.Serializable id, org.hibernate.LockMode lockMode)

		LoadEvent event = new LoadEvent(id, entityName, lockMode, this);
	   	fireLoad(event, LoadEventListener.GET);
		return event.getResult();
	
public org.hibernate.engine.ActionQueuegetActionQueue()

		errorIfClosed();
		checkTransactionSynchStatus();
		return actionQueue;
	
public org.hibernate.jdbc.BatchergetBatcher()

		errorIfClosed();
		checkTransactionSynchStatus();
		// TODO : should remove this exposure
		//  and have all references to the session's batcher use the ConnectionManager.
		return jdbcContext.getConnectionManager().getBatcher();
	
public org.hibernate.CacheModegetCacheMode()

		checkTransactionSynchStatus();
		return cacheMode;
	
public org.hibernate.ConnectionReleaseModegetConnectionReleaseMode()

		checkTransactionSynchStatus();
		return connectionReleaseMode;
	
public java.io.SerializablegetContextEntityIdentifier(java.lang.Object object)
Get the id value for an object that is actually associated with the session. This is a bit stricter than getEntityIdentifierIfNotUnsaved().

		errorIfClosed();
		if ( object instanceof HibernateProxy ) {
			return getProxyIdentifier(object);
		}
		else {
			EntityEntry entry = persistenceContext.getEntry(object);
			return entry != null ? entry.getId() : null;
		}
	
public org.hibernate.LockModegetCurrentLockMode(java.lang.Object object)

		errorIfClosed();
		checkTransactionSynchStatus();
		if ( object == null ) {
			throw new NullPointerException( "null object passed to getCurrentLockMode()" );
		}
		if ( object instanceof HibernateProxy ) {
			object = ( (HibernateProxy) object ).getHibernateLazyInitializer().getImplementation(this);
			if ( object == null ) {
				return LockMode.NONE;
			}
		}
		EntityEntry e = persistenceContext.getEntry(object);
		if ( e == null ) {
			throw new TransientObjectException( "Given object not associated with the session" );
		}
		if ( e.getStatus() != Status.MANAGED ) {
			throw new ObjectDeletedException( 
					"The given object was deleted", 
					e.getId(), 
					e.getPersister().getEntityName() 
				);
		}
		return e.getLockMode();
	
public intgetDontFlushFromFind()

		return dontFlushFromFind;
	
public org.hibernate.FiltergetEnabledFilter(java.lang.String filterName)

		checkTransactionSynchStatus();
		return (Filter) enabledFilters.get(filterName);
	
public java.util.MapgetEnabledFilters()

		errorIfClosed();
		checkTransactionSynchStatus();
		// First, validate all the enabled filters...
		//TODO: this implementation has bad performance
		Iterator itr = enabledFilters.values().iterator();
		while ( itr.hasNext() ) {
			final Filter filter = (Filter) itr.next();
			filter.validate();
		}
		return enabledFilters;
	
public org.hibernate.EntityModegetEntityMode()

		checkTransactionSynchStatus();
		return entityMode;
	
public java.lang.StringgetEntityName(java.lang.Object object)

		errorIfClosed();
		checkTransactionSynchStatus();
		if (object instanceof HibernateProxy) {
			if ( !persistenceContext.containsProxy( object ) ) {
				throw new TransientObjectException("proxy was not associated with the session");
			}
			object = ( (HibernateProxy) object ).getHibernateLazyInitializer().getImplementation();
		}

		EntityEntry entry = persistenceContext.getEntry(object);
		if ( entry == null ) {
			throwTransientObjectException( object );
		}
		return entry.getPersister().getEntityName();
	
public org.hibernate.persister.entity.EntityPersistergetEntityPersister(java.lang.String entityName, java.lang.Object object)

		errorIfClosed();
		if (entityName==null) {
			return factory.getEntityPersister( guessEntityName( object ) );
		}
		else {
			// try block is a hack around fact that currently tuplizers are not
			// given the opportunity to resolve a subclass entity name.  this
			// allows the (we assume custom) interceptor the ability to
			// influence this decision if we were not able to based on the
			// given entityName
			try {
				return factory.getEntityPersister( entityName )
						.getSubclassEntityPersister( object, getFactory(), entityMode );
			}
			catch( HibernateException e ) {
				try {
					return getEntityPersister( null, object );
				}
				catch( HibernateException e2 ) {
					throw e;
				}
			}
		}
	
public java.lang.ObjectgetEntityUsingInterceptor(org.hibernate.engine.EntityKey key)

		errorIfClosed();
		// todo : should this get moved to PersistentContext?
		// logically, is PersistentContext the "thing" to which an interceptor gets attached?
		final Object result = persistenceContext.getEntity(key);
		if ( result == null ) {
			final Object newObject = interceptor.getEntity( key.getEntityName(), key.getIdentifier() );
			if ( newObject != null ) {
				lock( newObject, LockMode.NONE );
			}
			return newObject;
		}
		else {
			return result;
		}
	
public java.lang.StringgetFetchProfile()

		checkTransactionSynchStatus();
		return fetchProfile;
	
public org.hibernate.type.TypegetFilterParameterType(java.lang.String filterParameterName)

		errorIfClosed();
		checkTransactionSynchStatus();
		String[] parsed = parseFilterParameterName(filterParameterName);
		FilterDefinition filterDef = factory.getFilterDefinition( parsed[0] );
		if (filterDef == null) {
			throw new IllegalArgumentException("Filter [" + parsed[0] + "] not defined");
		}
		Type type = filterDef.getParameterType( parsed[1] );
		if (type == null) {
			// this is an internal error of some sort...
			throw new InternalError("Unable to locate type for filter parameter");
		}
		return type;
	
public java.lang.ObjectgetFilterParameterValue(java.lang.String filterParameterName)

		errorIfClosed();
		checkTransactionSynchStatus();
		String[] parsed = parseFilterParameterName(filterParameterName);
		FilterImpl filter = (FilterImpl) enabledFilters.get( parsed[0] );
		if (filter == null) {
			throw new IllegalArgumentException("Filter [" + parsed[0] + "] currently not enabled");
		}
		return filter.getParameter( parsed[1] );
	
private org.hibernate.engine.query.FilterQueryPlangetFilterQueryPlan(java.lang.Object collection, java.lang.String filter, org.hibernate.engine.QueryParameters parameters, boolean shallow)

		if ( collection == null ) {
			throw new NullPointerException( "null collection passed to filter" );
		}

		CollectionEntry entry = persistenceContext.getCollectionEntryOrNull( collection );
		final CollectionPersister roleBeforeFlush = (entry == null) ? null : entry.getLoadedPersister();

		FilterQueryPlan plan = null;
		if ( roleBeforeFlush == null ) {
			// if it was previously unreferenced, we need to flush in order to
			// get its state into the database in order to execute query
			flush();
			entry = persistenceContext.getCollectionEntryOrNull( collection );
			CollectionPersister roleAfterFlush = (entry == null) ? null : entry.getLoadedPersister();
			if ( roleAfterFlush == null ) {
				throw new QueryException( "The collection was unreferenced" );
			}
			plan = factory.getQueryPlanCache().getFilterQueryPlan( filter, roleAfterFlush.getRole(), shallow, getEnabledFilters() );
		}
		else {
			// otherwise, we only need to flush if there are in-memory changes
			// to the queried tables
			plan = factory.getQueryPlanCache().getFilterQueryPlan( filter, roleBeforeFlush.getRole(), shallow, getEnabledFilters() );
			if ( autoFlushIfRequired( plan.getQuerySpaces() ) ) {
				// might need to run a different filter entirely after the flush
				// because the collection role may have changed
				entry = persistenceContext.getCollectionEntryOrNull( collection );
				CollectionPersister roleAfterFlush = (entry == null) ? null : entry.getLoadedPersister();
				if ( roleBeforeFlush != roleAfterFlush ) {
					if ( roleAfterFlush == null ) {
						throw new QueryException( "The collection was dereferenced" );
					}
					plan = factory.getQueryPlanCache().getFilterQueryPlan( filter, roleAfterFlush.getRole(), shallow, getEnabledFilters() );
				}
			}
		}

		if ( parameters != null ) {
			parameters.getPositionalParameterValues()[0] = entry.getLoadedKey();
			parameters.getPositionalParameterTypes()[0] = entry.getLoadedPersister().getKeyType();
		}

		return plan;
	
public org.hibernate.FlushModegetFlushMode()

		checkTransactionSynchStatus();
		return flushMode;
	
public java.io.SerializablegetIdentifier(java.lang.Object object)

		errorIfClosed();
		checkTransactionSynchStatus();
		if ( object instanceof HibernateProxy ) {
			LazyInitializer li = ( (HibernateProxy) object ).getHibernateLazyInitializer();
			if ( li.getSession() != this ) {
				throw new TransientObjectException( "The proxy was not associated with this session" );
			}
			return li.getIdentifier();
		}
		else {
			EntityEntry entry = persistenceContext.getEntry(object);
			if ( entry == null ) {
				throw new TransientObjectException( "The instance was not associated with this session" );
			}
			return entry.getId();
		}
	
public org.hibernate.InterceptorgetInterceptor()

		checkTransactionSynchStatus();
		return interceptor;
	
public org.hibernate.jdbc.JDBCContextgetJDBCContext()

		errorIfClosed();
		checkTransactionSynchStatus();
		return jdbcContext;
	
public org.hibernate.event.EventListenersgetListeners()

		return listeners;
	
public org.hibernate.QuerygetNamedQuery(java.lang.String queryName)

		errorIfClosed();
		checkTransactionSynchStatus();
		return super.getNamedQuery(queryName);
	
private org.hibernate.persister.entity.OuterJoinLoadablegetOuterJoinLoadable(java.lang.String entityName)

		EntityPersister persister = factory.getEntityPersister(entityName);
		if ( !(persister instanceof OuterJoinLoadable) ) {
			throw new MappingException( "class persister is not OuterJoinLoadable: " + entityName );
		}
		return ( OuterJoinLoadable ) persister;
	
public org.hibernate.engine.PersistenceContextgetPersistenceContext()

		errorIfClosed();
		checkTransactionSynchStatus();
		return persistenceContext;
	
private java.io.SerializablegetProxyIdentifier(java.lang.Object proxy)

		return ( (HibernateProxy) proxy ).getHibernateLazyInitializer().getIdentifier();
	
public org.hibernate.SessiongetSession(org.hibernate.EntityMode entityMode)

		if ( this.entityMode == entityMode ) {
			return this;
		}

		if ( rootSession != null ) {
			rootSession.getSession( entityMode );
		}

		errorIfClosed();
		checkTransactionSynchStatus();

		SessionImpl rtn = null;
		if ( childSessionsByEntityMode == null ) {
			childSessionsByEntityMode = new HashMap();
		}
		else {
			rtn = (SessionImpl) childSessionsByEntityMode.get( entityMode );
		}

		if ( rtn == null ) {
			rtn = new SessionImpl( this, entityMode );
			childSessionsByEntityMode.put( entityMode, rtn );
		}

		return rtn;
	
public org.hibernate.SessionFactorygetSessionFactory()

		checkTransactionSynchStatus();
		return factory;
	
public org.hibernate.stat.SessionStatisticsgetStatistics()

		checkTransactionSynchStatus();
		return new SessionStatisticsImpl(this);
	
public longgetTimestamp()

		checkTransactionSynchStatus();
		return timestamp;
	
public org.hibernate.TransactiongetTransaction()

		errorIfClosed();
		return jdbcContext.getTransaction();
	
public java.lang.StringguessEntityName(java.lang.Object object)

		errorIfClosed();
		String entity = interceptor.getEntityName( object );
		if ( entity == null ) {
			if ( object instanceof Map ) {
				entity = (String) ( (Map) object ).get( DynamicMapInstantiator.KEY );
				if ( entity == null ) {
					throw new HibernateException( "could not determine type of dynamic entity" );
				}
			}
			else if ( object instanceof Element ) {
				// TODO : really need to keep a map of nodeName -> entityName, but that would mean nodeName being distinct
				entity = ( (Element) object ).getName();
			}
			else {
				entity = object.getClass().getName();
			}
		}
		return entity;
	
public java.lang.ObjectimmediateLoad(java.lang.String entityName, java.io.Serializable id)
Load the data for the object with the specified id into a newly created object. This is only called when lazily initializing a proxy. Do NOT return a proxy.

		if ( log.isDebugEnabled() ) {
			EntityPersister persister = getFactory().getEntityPersister(entityName);
			log.debug( "initializing proxy: " + MessageHelper.infoString( persister, id, getFactory() ) );
		}
		
		LoadEvent event = new LoadEvent(id, entityName, true, this);
		fireLoad(event, LoadEventListener.IMMEDIATE_LOAD);
		return event.getResult();
	
public voidinitializeCollection(org.hibernate.collection.PersistentCollection collection, boolean writing)

		errorIfClosed();
		checkTransactionSynchStatus();
		InitializeCollectionEventListener[] listener = listeners.getInitializeCollectionEventListeners();
		for ( int i = 0; i < listener.length; i++ ) {
			listener[i].onInitializeCollection( new InitializeCollectionEvent(collection, this) );
		}
	
public java.lang.Objectinstantiate(java.lang.String entityName, java.io.Serializable id)

		return instantiate( factory.getEntityPersister(entityName), id );
	
public java.lang.Objectinstantiate(org.hibernate.persister.entity.EntityPersister persister, java.io.Serializable id)
give the interceptor an opportunity to override the default instantiation

		errorIfClosed();
		checkTransactionSynchStatus();
		Object result = interceptor.instantiate( persister.getEntityName(), entityMode, id );
		if ( result == null ) {
			result = persister.instantiate( id, entityMode );
		}
		return result;
	
public java.lang.ObjectinternalLoad(java.lang.String entityName, java.io.Serializable id, boolean eager, boolean nullable)

		// todo : remove
		LoadEventListener.LoadType type = nullable ? 
				LoadEventListener.INTERNAL_LOAD_NULLABLE : 
				eager ? LoadEventListener.INTERNAL_LOAD_EAGER : LoadEventListener.INTERNAL_LOAD_LAZY;
		LoadEvent event = new LoadEvent(id, entityName, true, this);
		fireLoad(event, type);
		if ( !nullable ) {
			UnresolvableObjectException.throwIfNull( event.getResult(), id, entityName );
		}
		return event.getResult();
	
public booleanisAutoCloseSessionEnabled()

		return autoCloseSessionEnabled;
	
public booleanisConnected()

		checkTransactionSynchStatus();
		return !isClosed() && jdbcContext.getConnectionManager().isCurrentlyConnected();
	
public booleanisDirty()

		errorIfClosed();
		checkTransactionSynchStatus();
		log.debug("checking session dirtiness");
		if ( actionQueue.areInsertionsOrDeletionsQueued() ) {
			log.debug("session dirty (scheduled updates and insertions)");
			return true;
		}
		else {
			DirtyCheckEvent event = new DirtyCheckEvent(this);
			DirtyCheckEventListener[] dirtyCheckEventListener = listeners.getDirtyCheckEventListeners();
			for ( int i = 0; i < dirtyCheckEventListener.length; i++ ) {
				dirtyCheckEventListener[i].onDirtyCheck(event);
			}
			return event.isDirty();
		}
	
public booleanisEventSource()

		checkTransactionSynchStatus();
		return true;
	
public booleanisFlushBeforeCompletionEnabled()

		return flushBeforeCompletionEnabled;
	
public booleanisFlushModeNever()

		return FlushMode.isManualFlushMode( getFlushMode() );
	
public booleanisOpen()

		checkTransactionSynchStatus();
		return !isClosed();
	
public booleanisTransactionInProgress()

		checkTransactionSynchStatus();
		return !isClosed() && jdbcContext.isTransactionInProgress();
	
public java.util.Iteratoriterate(java.lang.String query)

		return iterate( query, new QueryParameters() );
	
public java.util.Iteratoriterate(java.lang.String query, java.lang.Object value, org.hibernate.type.Type type)

		return iterate( query, new QueryParameters(type, value) );
	
public java.util.Iteratoriterate(java.lang.String query, java.lang.Object[] values, org.hibernate.type.Type[] types)

		return iterate( query, new QueryParameters(types, values) );
	
public java.util.Iteratoriterate(java.lang.String query, org.hibernate.engine.QueryParameters queryParameters)

		errorIfClosed();
		checkTransactionSynchStatus();
		queryParameters.validateParameters();
		HQLQueryPlan plan = getHQLQueryPlan( query, true );
		autoFlushIfRequired( plan.getQuerySpaces() );

		dontFlushFromFind++; //stops flush being called multiple times if this method is recursively called
		try {
			return plan.performIterate( queryParameters, this );
		}
		finally {
			dontFlushFromFind--;
		}
	
public java.util.IteratoriterateFilter(java.lang.Object collection, java.lang.String filter, org.hibernate.engine.QueryParameters queryParameters)

		errorIfClosed();
		checkTransactionSynchStatus();
		FilterQueryPlan plan = getFilterQueryPlan( collection, filter, queryParameters, true );
		return plan.performIterate( queryParameters, this );
	
public java.util.Listlist(java.lang.String query, org.hibernate.engine.QueryParameters queryParameters)

		errorIfClosed();
		checkTransactionSynchStatus();
		queryParameters.validateParameters();
		HQLQueryPlan plan = getHQLQueryPlan( query, false );
		autoFlushIfRequired( plan.getQuerySpaces() );

		List results = CollectionHelper.EMPTY_LIST;
		boolean success = false;

		dontFlushFromFind++;   //stops flush being called multiple times if this method is recursively called
		try {
			results = plan.performList( queryParameters, this );
			success = true;
		}
		finally {
			dontFlushFromFind--;
			afterOperation(success);
		}
		return results;
	
public java.util.Listlist(CriteriaImpl criteria)

		errorIfClosed();
		checkTransactionSynchStatus();
		String[] implementors = factory.getImplementors( criteria.getEntityOrClassName() );
		int size = implementors.length;

		CriteriaLoader[] loaders = new CriteriaLoader[size];
		Set spaces = new HashSet();
		for( int i=0; i <size; i++ ) {

			loaders[i] = new CriteriaLoader(
					getOuterJoinLoadable( implementors[i] ),
					factory,
					criteria,
					implementors[i],
					getEnabledFilters()
				);

			spaces.addAll( loaders[i].getQuerySpaces() );

		}

		autoFlushIfRequired(spaces);

		List results = Collections.EMPTY_LIST;
		dontFlushFromFind++;
		boolean success = false;
		try {
			for( int i=0; i<size; i++ ) {
				final List currentResults = loaders[i].list(this);
				currentResults.addAll(results);
				results = currentResults;
			}
			success = true;
		}
		finally {
			dontFlushFromFind--;
			afterOperation(success);
		}

		return results;
	
public java.util.ListlistCustomQuery(org.hibernate.loader.custom.CustomQuery customQuery, org.hibernate.engine.QueryParameters queryParameters)

		errorIfClosed();
		checkTransactionSynchStatus();

		if ( log.isTraceEnabled() ) {
			log.trace( "SQL query: " + customQuery.getSQL() );
		}
		
		CustomLoader loader = new CustomLoader( customQuery, getFactory() );

		autoFlushIfRequired( loader.getQuerySpaces() );

		dontFlushFromFind++;
		boolean success = false;
		try {
			List results = loader.list(this, queryParameters);
			success = true;
			return results;
		}
		finally {
			dontFlushFromFind--;
			afterOperation(success);
		}
	
public java.util.ListlistFilter(java.lang.Object collection, java.lang.String filter, org.hibernate.engine.QueryParameters queryParameters)

		errorIfClosed();
		checkTransactionSynchStatus();
		FilterQueryPlan plan = getFilterQueryPlan( collection, filter, queryParameters, false );
		List results = CollectionHelper.EMPTY_LIST;

		boolean success = false;
		dontFlushFromFind++;   //stops flush being called multiple times if this method is recursively called
		try {
			results = plan.performList( queryParameters, this );
			success = true;
		}
		finally {
			dontFlushFromFind--;
			afterOperation(success);
		}
		return results;
	
public voidload(java.lang.Object object, java.io.Serializable id)

		LoadEvent event = new LoadEvent(id, object, this);
		fireLoad( event, LoadEventListener.RELOAD );
	
public java.lang.Objectload(java.lang.Class entityClass, java.io.Serializable id)

		return load( entityClass.getName(), id );
	
public java.lang.Objectload(java.lang.String entityName, java.io.Serializable id)

		LoadEvent event = new LoadEvent(id, entityName, false, this);
		boolean success = false;
		try {
			fireLoad( event, LoadEventListener.LOAD );
			if ( event.getResult() == null ) {
				getFactory().getEntityNotFoundDelegate().handleEntityNotFound( entityName, id );
			}
			success = true;
			return event.getResult();
		}
		finally {
			afterOperation(success);
		}
	
public java.lang.Objectload(java.lang.Class entityClass, java.io.Serializable id, org.hibernate.LockMode lockMode)

		return load( entityClass.getName(), id, lockMode );
	
public java.lang.Objectload(java.lang.String entityName, java.io.Serializable id, org.hibernate.LockMode lockMode)

		LoadEvent event = new LoadEvent(id, entityName, lockMode, this);
		fireLoad( event, LoadEventListener.LOAD );
		return event.getResult();
	
public voidlock(java.lang.String entityName, java.lang.Object object, org.hibernate.LockMode lockMode)

		fireLock( new LockEvent(entityName, object, lockMode, this) );
	
public voidlock(java.lang.Object object, org.hibernate.LockMode lockMode)

		fireLock( new LockEvent(object, lockMode, this) );
	
public voidmanagedClose()

		log.trace( "automatically closing session" );
		close();
	
public voidmanagedFlush()

		if ( isClosed() ) {
			log.trace( "skipping auto-flush due to session closed" );
			return;
		}
		log.trace("automatically flushing session");
		flush();
		
		if ( childSessionsByEntityMode != null ) {
			Iterator iter = childSessionsByEntityMode.values().iterator();
			while ( iter.hasNext() ) {
				( (Session) iter.next() ).flush();
			}
		}
	
public java.lang.Objectmerge(java.lang.String entityName, java.lang.Object object)

		return fireMerge( new MergeEvent(entityName, object, this) );
	
public java.lang.Objectmerge(java.lang.Object object)

		return merge(null, object);
	
public voidmerge(java.lang.String entityName, java.lang.Object object, java.util.Map copiedAlready)

		fireMerge( copiedAlready, new MergeEvent(entityName, object, this) );
	
private java.lang.String[]parseFilterParameterName(java.lang.String filterParameterName)

		int dot = filterParameterName.indexOf('.");
		if (dot <= 0) {
			throw new IllegalArgumentException("Invalid filter-parameter name format"); // TODO: what type?
		}
		String filterName = filterParameterName.substring(0, dot);
		String parameterName = filterParameterName.substring(dot+1);
		return new String[] {filterName, parameterName};
	
public voidpersist(java.lang.String entityName, java.lang.Object object)

		firePersist( new PersistEvent(entityName, object, this) );
	
public voidpersist(java.lang.Object object)

		persist(null, object);
	
public voidpersist(java.lang.String entityName, java.lang.Object object, java.util.Map copiedAlready)

		firePersist( copiedAlready, new PersistEvent(entityName, object, this) );
	
public voidpersistOnFlush(java.lang.String entityName, java.lang.Object object)

		firePersistOnFlush( new PersistEvent(entityName, object, this) );
	
public voidpersistOnFlush(java.lang.Object object)

		persist(null, object);
	
public voidpersistOnFlush(java.lang.String entityName, java.lang.Object object, java.util.Map copiedAlready)

		firePersistOnFlush( copiedAlready, new PersistEvent(entityName, object, this) );
	
private voidreadObject(java.io.ObjectInputStream ois)
Used by JDK serialization...

param
ois The input stream from which we are being read...
throws
IOException Indicates a general IO stream exception
throws
ClassNotFoundException Indicates a class resolution issue

		log.trace( "deserializing session" );

		boolean isRootSession = ois.readBoolean();
		connectionReleaseMode = ConnectionReleaseMode.parse( ( String ) ois.readObject() );
		entityMode = EntityMode.parse( ( String ) ois.readObject() );
		autoClear = ois.readBoolean();
		flushMode = FlushMode.parse( ( String ) ois.readObject() );
		cacheMode = CacheMode.parse( ( String ) ois.readObject() );
		flushBeforeCompletionEnabled = ois.readBoolean();
		autoCloseSessionEnabled = ois.readBoolean();
		fetchProfile = ( String ) ois.readObject();
		interceptor = ( Interceptor ) ois.readObject();

		factory = SessionFactoryImpl.deserialize( ois );
		listeners = factory.getEventListeners();

		if ( isRootSession ) {
			jdbcContext = JDBCContext.deserialize( ois, this, interceptor );
		}

		persistenceContext = StatefulPersistenceContext.deserialize( ois, this );
		actionQueue = ActionQueue.deserialize( ois, this );

		enabledFilters = ( Map ) ois.readObject();
		childSessionsByEntityMode = ( Map ) ois.readObject();

		Iterator iter = enabledFilters.values().iterator();
		while ( iter.hasNext() ) {
			( ( FilterImpl ) iter.next() ).afterDeserialize(factory);
		}

		if ( isRootSession && childSessionsByEntityMode != null ) {
			iter = childSessionsByEntityMode.values().iterator();
			while ( iter.hasNext() ) {
				final SessionImpl child = ( ( SessionImpl ) iter.next() );
				child.rootSession = this;
				child.jdbcContext = this.jdbcContext;
			}
		}
	
public voidreconnect()

		errorIfClosed();
		log.debug( "reconnecting session" );
		checkTransactionSynchStatus();
		jdbcContext.getConnectionManager().manualReconnect();
	
public voidreconnect(java.sql.Connection conn)

		errorIfClosed();
		log.debug( "reconnecting session" );
		checkTransactionSynchStatus();
		jdbcContext.getConnectionManager().manualReconnect( conn );
	
public voidrefresh(java.lang.Object object)

		fireRefresh( new RefreshEvent(object, this) );
	
public voidrefresh(java.lang.Object object, org.hibernate.LockMode lockMode)

		fireRefresh( new RefreshEvent(object, lockMode, this) );
	
public voidrefresh(java.lang.Object object, java.util.Map refreshedAlready)

		fireRefresh( refreshedAlready, new RefreshEvent(object, this) );
	
public voidreplicate(java.lang.Object obj, org.hibernate.ReplicationMode replicationMode)

		fireReplicate( new ReplicateEvent(obj, replicationMode, this) );
	
public voidreplicate(java.lang.String entityName, java.lang.Object obj, org.hibernate.ReplicationMode replicationMode)

		fireReplicate( new ReplicateEvent(entityName, obj, replicationMode, this) );
	
public voidsave(java.lang.Object obj, java.io.Serializable id)

		save(null, obj, id);
	
public java.io.Serializablesave(java.lang.Object obj)

		return save(null, obj);
	
public java.io.Serializablesave(java.lang.String entityName, java.lang.Object object)

		return fireSave( new SaveOrUpdateEvent(entityName, object, this) );
	
public voidsave(java.lang.String entityName, java.lang.Object object, java.io.Serializable id)

		fireSave( new SaveOrUpdateEvent(entityName, object, id, this) );
	
public voidsaveOrUpdate(java.lang.Object object)

		saveOrUpdate(null, object);
	
public voidsaveOrUpdate(java.lang.String entityName, java.lang.Object obj)

		fireSaveOrUpdate( new SaveOrUpdateEvent(entityName, obj, this) );
	
public java.lang.ObjectsaveOrUpdateCopy(java.lang.String entityName, java.lang.Object object)

		return fireSaveOrUpdateCopy( new MergeEvent(entityName, object, this) );
	
public java.lang.ObjectsaveOrUpdateCopy(java.lang.Object object)

		return saveOrUpdateCopy( null, object );
	
public java.lang.ObjectsaveOrUpdateCopy(java.lang.String entityName, java.lang.Object object, java.io.Serializable id)

		return fireSaveOrUpdateCopy( new MergeEvent(entityName, object, id, this) );
	
public java.lang.ObjectsaveOrUpdateCopy(java.lang.Object object, java.io.Serializable id)

		return saveOrUpdateCopy( null, object, id );
	
public voidsaveOrUpdateCopy(java.lang.String entityName, java.lang.Object object, java.util.Map copiedAlready)

		fireSaveOrUpdateCopy( copiedAlready, new MergeEvent( entityName, object, this ) );
	
public org.hibernate.ScrollableResultsscroll(java.lang.String query, org.hibernate.engine.QueryParameters queryParameters)

		errorIfClosed();
		checkTransactionSynchStatus();
		HQLQueryPlan plan = getHQLQueryPlan( query, false );
		autoFlushIfRequired( plan.getQuerySpaces() );
		dontFlushFromFind++;
		try {
			return plan.performScroll( queryParameters, this );
		}
		finally {
			dontFlushFromFind--;
		}
	
public org.hibernate.ScrollableResultsscroll(CriteriaImpl criteria, org.hibernate.ScrollMode scrollMode)

		errorIfClosed();
		checkTransactionSynchStatus();
		String entityName = criteria.getEntityOrClassName();
		CriteriaLoader loader = new CriteriaLoader(
				getOuterJoinLoadable(entityName),
				factory,
				criteria,
				entityName,
				getEnabledFilters()
		);
		autoFlushIfRequired( loader.getQuerySpaces() );
		dontFlushFromFind++;
		try {
			return loader.scroll(this, scrollMode);
		}
		finally {
			dontFlushFromFind--;
		}
	
public org.hibernate.ScrollableResultsscrollCustomQuery(org.hibernate.loader.custom.CustomQuery customQuery, org.hibernate.engine.QueryParameters queryParameters)

		errorIfClosed();
		checkTransactionSynchStatus();

		if ( log.isTraceEnabled() ) {
			log.trace( "scroll SQL query: " + customQuery.getSQL() );
		}

		CustomLoader loader = new CustomLoader( customQuery, getFactory() );

		autoFlushIfRequired( loader.getQuerySpaces() );

		dontFlushFromFind++; //stops flush being called multiple times if this method is recursively called
		try {
			return loader.scroll(queryParameters, this);
		}
		finally {
			dontFlushFromFind--;
		}
	
public voidsetAutoClear(boolean enabled)

		errorIfClosed();
		autoClear = enabled;
	
public voidsetCacheMode(org.hibernate.CacheMode cacheMode)

		errorIfClosed();
		checkTransactionSynchStatus();
		if ( log.isTraceEnabled() ) {
			log.trace("setting cache mode to: " + cacheMode);
		}
		this.cacheMode= cacheMode; 
	
public voidsetFetchProfile(java.lang.String fetchProfile)

		errorIfClosed();
		checkTransactionSynchStatus();
		this.fetchProfile = fetchProfile;
	
public voidsetFlushMode(org.hibernate.FlushMode flushMode)

		errorIfClosed();
		checkTransactionSynchStatus();
		if ( log.isTraceEnabled() ) {
			log.trace("setting flush mode to: " + flushMode);
		}
		this.flushMode = flushMode;
	
public voidsetReadOnly(java.lang.Object entity, boolean readOnly)

		errorIfClosed();
		checkTransactionSynchStatus();
		persistenceContext.setReadOnly(entity, readOnly);
	
public booleanshouldAutoClose()

		return isAutoCloseSessionEnabled() && !isClosed();
	
private voidthrowTransientObjectException(java.lang.Object object)

		throw new TransientObjectException(
				"object references an unsaved transient instance - save the transient instance before flushing: " +
				guessEntityName(object)
			);
	
public java.lang.StringtoString()

		StringBuffer buf = new StringBuffer(500)
			.append( "SessionImpl(" );
		if ( !isClosed() ) {
			buf.append(persistenceContext)
				.append(";")
				.append(actionQueue);
		}
		else {
			buf.append("<closed>");
		}
		return buf.append(')").toString();
	
public voidupdate(java.lang.Object obj)

		update(null, obj);
	
public voidupdate(java.lang.Object obj, java.io.Serializable id)

		update(null, obj, id);
	
public voidupdate(java.lang.String entityName, java.lang.Object object)

		fireUpdate( new SaveOrUpdateEvent(entityName, object, this) );
	
public voidupdate(java.lang.String entityName, java.lang.Object object, java.io.Serializable id)

		fireUpdate(new SaveOrUpdateEvent(entityName, object, id, this));
	
private voidwriteObject(java.io.ObjectOutputStream oos)
Used by JDK serialization...

param
oos The output stream to which we are being written...
throws
IOException Indicates a general IO stream exception

		if ( !jdbcContext.getConnectionManager().isReadyForSerialization() ) {
			throw new IllegalStateException( "Cannot serialize a session while connected" );
		}

		log.trace( "serializing session" );

		oos.writeBoolean( rootSession == null );
		oos.writeObject( connectionReleaseMode.toString() );
		oos.writeObject( entityMode.toString() );
		oos.writeBoolean( autoClear );
		oos.writeObject( flushMode.toString() );
		oos.writeObject( cacheMode.toString() );
		oos.writeBoolean( flushBeforeCompletionEnabled );
		oos.writeBoolean( autoCloseSessionEnabled );
		oos.writeObject( fetchProfile );
		// we need to writeObject() on this since interceptor is user defined
		oos.writeObject( interceptor );

		factory.serialize( oos );

		if ( rootSession == null ) {
			jdbcContext.serialize( oos );
		}

		persistenceContext.serialize( oos );
		actionQueue.serialize( oos );

		// todo : look at optimizing these...
		oos.writeObject( enabledFilters );
		oos.writeObject( childSessionsByEntityMode );