📄 sessionimpl.java
字号:
//$Id: SessionImpl.java 10688 2006-11-02 18:53:25Z steve.ebersole@jboss.com $package org.hibernate.impl;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.Serializable;import java.sql.Connection;import java.sql.SQLException;import java.util.Collection;import java.util.Collections;import java.util.HashMap;import java.util.HashSet;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Set;import org.dom4j.Element;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.hibernate.CacheMode;import org.hibernate.ConnectionReleaseMode;import org.hibernate.Criteria;import org.hibernate.EntityMode;import org.hibernate.Filter;import org.hibernate.FlushMode;import org.hibernate.HibernateException;import org.hibernate.Interceptor;import org.hibernate.LockMode;import org.hibernate.MappingException;import org.hibernate.ObjectDeletedException;import org.hibernate.Query;import org.hibernate.QueryException;import org.hibernate.ReplicationMode;import org.hibernate.SQLQuery;import org.hibernate.ScrollMode;import org.hibernate.ScrollableResults;import org.hibernate.Session;import org.hibernate.SessionException;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.TransientObjectException;import org.hibernate.UnresolvableObjectException;import org.hibernate.collection.PersistentCollection;import org.hibernate.engine.ActionQueue;import org.hibernate.engine.CollectionEntry;import org.hibernate.engine.EntityEntry;import org.hibernate.engine.EntityKey;import org.hibernate.engine.FilterDefinition;import org.hibernate.engine.PersistenceContext;import org.hibernate.engine.QueryParameters;import org.hibernate.engine.StatefulPersistenceContext;import org.hibernate.engine.Status;import org.hibernate.engine.query.FilterQueryPlan;import org.hibernate.engine.query.HQLQueryPlan;import org.hibernate.engine.query.NativeSQLQueryPlan;import org.hibernate.engine.query.sql.NativeSQLQuerySpecification;import org.hibernate.event.AutoFlushEvent;import org.hibernate.event.AutoFlushEventListener;import org.hibernate.event.DeleteEvent;import org.hibernate.event.DeleteEventListener;import org.hibernate.event.DirtyCheckEvent;import org.hibernate.event.DirtyCheckEventListener;import org.hibernate.event.EventListeners;import org.hibernate.event.EventSource;import org.hibernate.event.EvictEvent;import org.hibernate.event.EvictEventListener;import org.hibernate.event.FlushEvent;import org.hibernate.event.FlushEventListener;import org.hibernate.event.InitializeCollectionEvent;import org.hibernate.event.InitializeCollectionEventListener;import org.hibernate.event.LoadEvent;import org.hibernate.event.LoadEventListener;import org.hibernate.event.LoadEventListener.LoadType;import org.hibernate.event.LockEvent;import org.hibernate.event.LockEventListener;import org.hibernate.event.MergeEvent;import org.hibernate.event.MergeEventListener;import org.hibernate.event.PersistEvent;import org.hibernate.event.PersistEventListener;import org.hibernate.event.RefreshEvent;import org.hibernate.event.RefreshEventListener;import org.hibernate.event.ReplicateEvent;import org.hibernate.event.ReplicateEventListener;import org.hibernate.event.SaveOrUpdateEvent;import org.hibernate.event.SaveOrUpdateEventListener;import org.hibernate.exception.JDBCExceptionHelper;import org.hibernate.jdbc.Batcher;import org.hibernate.jdbc.JDBCContext;import org.hibernate.jdbc.Work;import org.hibernate.loader.criteria.CriteriaLoader;import org.hibernate.loader.custom.CustomLoader;import org.hibernate.loader.custom.CustomQuery;import org.hibernate.persister.collection.CollectionPersister;import org.hibernate.persister.entity.EntityPersister;import org.hibernate.persister.entity.OuterJoinLoadable;import org.hibernate.pretty.MessageHelper;import org.hibernate.proxy.HibernateProxy;import org.hibernate.proxy.LazyInitializer;import org.hibernate.stat.SessionStatistics;import org.hibernate.stat.SessionStatisticsImpl;import org.hibernate.tuple.DynamicMapInstantiator;import org.hibernate.type.Type;import org.hibernate.util.ArrayHelper;import org.hibernate.util.CollectionHelper;import org.hibernate.util.StringHelper;/** * 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 */public final class SessionImpl extends AbstractSessionImpl implements EventSource, org.hibernate.classic.Session, JDBCContext.Context { // todo : need to find a clean way to handle the "event source" role // a seperate classs responsible for generating/dispatching events just duplicates most of the Session methods... // passing around seperate reto interceptor, factory, actionQueue, and persistentContext is not manageable... private static final Logger log = LoggerFactory.getLogger(SessionImpl.class); private transient EntityMode entityMode = EntityMode.POJO; private transient boolean autoClear; //for EJB3 private transient long timestamp; private transient FlushMode flushMode = FlushMode.AUTO; private transient CacheMode cacheMode = CacheMode.NORMAL; private transient Interceptor interceptor; private transient int dontFlushFromFind = 0; private transient ActionQueue actionQueue; private transient StatefulPersistenceContext persistenceContext; private transient JDBCContext jdbcContext; private transient EventListeners listeners; private transient boolean flushBeforeCompletionEnabled; private transient boolean autoCloseSessionEnabled; private transient ConnectionReleaseMode connectionReleaseMode; private transient String fetchProfile; private transient Map enabledFilters = new HashMap(); private transient Session rootSession; private transient Map childSessionsByEntityMode; /** * Constructor used in building "child sessions". * * @param parent The parent session * @param entityMode */ private SessionImpl(SessionImpl parent, EntityMode 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 + "]" ); } /** * 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. */ SessionImpl( final Connection connection, final SessionFactoryImpl factory, final boolean autoclose, final long timestamp, final Interceptor interceptor, final EntityMode entityMode, final boolean flushBeforeCompletionEnabled, final boolean autoCloseSessionEnabled, final ConnectionReleaseMode connectionReleaseMode) { 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 ); } } public Session getSession(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 void clear() { errorIfClosed(); checkTransactionSynchStatus(); persistenceContext.clear(); actionQueue.clear(); } public Batcher getBatcher() { errorIfClosed(); checkTransactionSynchStatus(); // TODO : should remove this exposure // and have all references to the session's batcher use the ConnectionManager. return jdbcContext.getConnectionManager().getBatcher(); } public long getTimestamp() { checkTransactionSynchStatus(); return timestamp; } public Connection close() throws HibernateException { 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 ConnectionReleaseMode getConnectionReleaseMode() { checkTransactionSynchStatus(); return connectionReleaseMode; } public boolean isAutoCloseSessionEnabled() { return autoCloseSessionEnabled; } public boolean isOpen() { checkTransactionSynchStatus(); return !isClosed(); } public boolean isFlushModeNever() { return FlushMode.isManualFlushMode( getFlushMode() ); } public boolean isFlushBeforeCompletionEnabled() { return flushBeforeCompletionEnabled; } public void managedFlush() { 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 boolean shouldAutoClose() { return isAutoCloseSessionEnabled() && !isClosed(); } public void managedClose() { log.trace( "automatically closing session" ); close(); } public Connection connection() throws HibernateException { errorIfClosed(); return jdbcContext.borrowConnection(); } public boolean isConnected() { checkTransactionSynchStatus(); return !isClosed() && jdbcContext.getConnectionManager().isCurrentlyConnected(); } public boolean isTransactionInProgress() { checkTransactionSynchStatus(); return !isClosed() && jdbcContext.isTransactionInProgress(); } public Connection disconnect() throws HibernateException { errorIfClosed(); log.debug( "disconnecting session" ); return jdbcContext.getConnectionManager().manualDisconnect(); } public void reconnect() throws HibernateException { errorIfClosed(); log.debug( "reconnecting session" ); checkTransactionSynchStatus(); jdbcContext.getConnectionManager().manualReconnect(); } public void reconnect(Connection conn) throws HibernateException { errorIfClosed(); log.debug( "reconnecting session" ); checkTransactionSynchStatus(); jdbcContext.getConnectionManager().manualReconnect( conn ); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -