`
周英能
  • 浏览: 185997 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

spring、hibernate源码分析二

 
阅读更多

从上篇文章分析得出,hibernate初始化时,flushBeforeCompletion、autoCloseSession默认为false

releaseMode为auto。还有hibernate.jdbc.batch_size默认为0等。那现在来分析openSession和getCurrentSession的区别就不难了。

    首先进入sessionFactory的实现类SessionFactoryImpl,接到上篇文章继续分析:

上篇文章的configuration最后调用代码如下:

 

return new SessionFactoryImpl(
				this,
				mapping,
				settings,
				getInitializedEventListeners(),
				sessionFactoryObserver
			);

 

public SessionFactoryImpl(
			Configuration cfg,
	        Mapping mapping,
	        Settings settings,
	        EventListeners listeners,
			SessionFactoryObserver observer) throws HibernateException {
                //省略
		currentSessionContext = buildCurrentSessionContext();
               //省略
	}

private CurrentSessionContext buildCurrentSessionContext() {
String impl = properties.getProperty( Environment.CURRENT_SESSION_CONTEXT_CLASS );
		// for backward-compatability
		if ( impl == null && transactionManager != null ) {
			impl = "jta";
		}

		if ( impl == null ) {
			return null;
		}
		else if ( "jta".equals( impl ) ) {
			if ( settings.getTransactionFactory().areCallbacksLocalToHibernateTransactions() ) {
				log.warn( "JTASessionContext being used with JDBCTransactionFactory; auto-flush will not operate correctly with getCurrentSession()" );
			}
			return new JTASessionContext( this );
		}
		else if ( "thread".equals( impl ) ) {
			return new ThreadLocalSessionContext( this );
		}
		else if ( "managed".equals( impl ) ) {
			return new ManagedSessionContext( this );
		}
		else {
			try {
				Class implClass = ReflectHelper.classForName( impl );
				return ( CurrentSessionContext ) implClass
						.getConstructor( new Class[] { SessionFactoryImplementor.class } )
						.newInstance( new Object[] { this } );
			}
			catch( Throwable t ) {
				log.error( "Unable to construct current session context [" + impl + "]", t );
				return null;
			}
		}
	}

 

 默认会采用jta事物

那么现在调用openSession继续追踪

 

public org.hibernate.classic.Session openSession() throws HibernateException {
		return openSession(interceptor);
	}


public org.hibernate.classic.Session openSession(Interceptor sessionLocalInterceptor)throws HibernateException 
{
long timestamp = settings.getRegionFactory().nextTimestamp();
return openSession( null, true, timestamp, sessionLocalInterceptor );
}

private SessionImpl openSession(
		Connection connection,
	    boolean autoClose,
	    long timestamp,
	    Interceptor sessionLocalInterceptor
	) {
		return new SessionImpl(
		        connection,
		        this,
		        autoClose,
		        timestamp,
		        sessionLocalInterceptor == null ? interceptor : sessionLocalInterceptor,
		        settings.getDefaultEntityMode(),
		        settings.isFlushBeforeCompletionEnabled(),
		        settings.isAutoCloseSessionEnabled(),
		        settings.getConnectionReleaseMode()
			);
	}

 

 发现通过openSession开启的Session有以下状态:flushBeforeCompletionEnabled=false,autoCloseSessionEnabled=false,connectionReleaseMode=true

调用getCurrentSession进行追踪:

 

public org.hibernate.classic.Session getCurrentSession() throws HibernateException {
		if ( currentSessionContext == null ) {
			throw new HibernateException( "No CurrentSessionContext configured!" );
		}
		return currentSessionContext.currentSession();
}

 

 进入ThreadLocalSessionContext继续追踪

 

public final Session currentSession() throws HibernateException {
		Session current = existingSession( factory );
		if (current == null) {
			current = buildOrObtainSession();
			// register a cleanup synch
			current.getTransaction().registerSynchronization( buildCleanupSynch() );
			// wrap the session in the transaction-protection proxy
			if ( needsWrapping( current ) ) {
				current = wrap( current );
			}
			// then bind it
			doBind( current, factory );
		}
		return current;
	}

 

protected Session buildOrObtainSession() {
return factory.openSession(
				null,
		        isAutoFlushEnabled(),
		        isAutoCloseEnabled(),
		        getConnectionReleaseMode()
			);
}

protected boolean isAutoFlushEnabled() {
		return true;
}

protected boolean isAutoCloseEnabled() {
		return true;
	}

 可看出getCurrentSession的状态

flushBeforeCompletionEnabled=true,autoCloseSessionEnabled=true,connectionReleaseMode=true

现在两种方式都是最终调用同一个方法,继续跟踪

 

public org.hibernate.classic.Session openSession(
			final Connection connection,
	        final boolean flushBeforeCompletionEnabled,
	        final boolean autoCloseSessionEnabled,
	        final ConnectionReleaseMode connectionReleaseMode) throws HibernateException {
		return new SessionImpl(
				connection,
		        this,
		        true,
		        settings.getRegionFactory().nextTimestamp(),
		        interceptor,
		        settings.getDefaultEntityMode(),
		        flushBeforeCompletionEnabled,
		        autoCloseSessionEnabled,
		        connectionReleaseMode
			);
	}
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 );

		loadQueryInfluencers = new LoadQueryInfluencers( factory );

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

		if ( log.isDebugEnabled() ) {
			log.debug( "opened session at timestamp: " + timestamp );
		}
	}

继续跟踪this.jdbcContext = new JDBCContext( this, connection, interceptor );session和collection的关联过程

 

public JDBCContext(Context owner, Connection connection, Interceptor interceptor) {
		this.owner = owner;
		this.connectionManager = new ConnectionManager(
		        owner.getFactory(),
		        this,
		        owner.getConnectionReleaseMode(),
		        connection,
		        interceptor
			);

		final boolean registerSynchronization = owner.isAutoCloseSessionEnabled()
		        || owner.isFlushBeforeCompletionEnabled()
		        || owner.getConnectionReleaseMode() == ConnectionReleaseMode.AFTER_TRANSACTION;
		if ( registerSynchronization ) {
			registerSynchronizationIfPossible();
		}
}

 继续跟踪ConnectionManager的创建过程

 

public ConnectionManager(
	        SessionFactoryImplementor factory,
	        Callback callback,
	        ConnectionReleaseMode releaseMode,
	        Connection connection,
	        Interceptor interceptor) {
		this.factory = factory;
		this.callback = callback;

		this.interceptor = interceptor;
		this.batcher = factory.getSettings().getBatcherFactory().createBatcher( this, interceptor );

		this.connection = connection;
		wasConnectionSupplied = ( connection != null );

		this.releaseMode = wasConnectionSupplied ? ConnectionReleaseMode.ON_CLOSE : releaseMode;
	}
public Connection getConnection() throws HibernateException {
		if ( isClosed ) {
			throw new HibernateException( "connection manager has been closed" );
		}
		if ( connection == null  ) {
			openConnection();
		}
		return connection;
	}
private void openConnection() throws HibernateException {
		if ( connection != null ) {
			return;
		}

		log.debug("opening JDBC connection");
		try {
			connection = factory.getConnectionProvider().getConnection();
		}
		catch (SQLException sqle) {
			throw JDBCExceptionHelper.convert(
					factory.getSQLExceptionConverter(),
					sqle,
					"Cannot open connection"
				);
		}

		callback.connectionOpened(); // register synch; stats.connect()
	}

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics