📄 sessionimpl.java
字号:
//$Id: SessionImpl.java 9321 2006-02-22 21:43:18Z steveebersole $
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.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.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Element;
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.ObjectNotFoundException;
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.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.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.event.LoadEventListener.LoadType;
import org.hibernate.jdbc.Batcher;
import org.hibernate.jdbc.JDBCContext;
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 references to interceptor, factory, actionQueue, and persistentContext is not manageable...
private static final Log log = LogFactory.getLog(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 ( rootSession != null ) {
rootSession.getSession( entityMode );
}
errorIfClosed();
checkTransactionSynchStatus();
if ( this.entityMode == entityMode ) {
return this;
}
if ( childSessionsByEntityMode == null ) {
childSessionsByEntityMode = new HashMap();
}
SessionImpl 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 getFlushMode() == FlushMode.NEVER;
}
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();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -