📄 sessionfactoryutils.java
字号:
/*
* Copyright 2002-2005 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.orm.hibernate3;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import javax.sql.DataSource;
import javax.transaction.Status;
import javax.transaction.Synchronization;
import javax.transaction.SystemException;
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.FlushMode;
import org.hibernate.HibernateException;
import org.hibernate.Interceptor;
import org.hibernate.JDBCException;
import org.hibernate.ObjectDeletedException;
import org.hibernate.ObjectNotFoundException;
import org.hibernate.PersistentObjectException;
import org.hibernate.Query;
import org.hibernate.QueryException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.StaleObjectStateException;
import org.hibernate.StaleStateException;
import org.hibernate.TransientObjectException;
import org.hibernate.UnresolvableObjectException;
import org.hibernate.WrongClassException;
import org.hibernate.connection.ConnectionProvider;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.engine.SessionImplementor;
import org.springframework.core.Ordered;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator;
import org.springframework.jdbc.support.SQLExceptionTranslator;
import org.springframework.jdbc.support.SQLStateSQLExceptionTranslator;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.util.Assert;
/**
* Helper class featuring methods for Hibernate Session handling,
* allowing for reuse of Hibernate Session instances within transactions.
*
* <p>Supports synchronization with both Spring-managed JTA transactions
* (i.e. JtaTransactionManager) and non-Spring JTA transactions (i.e. plain JTA
* or EJB CMT). See the <code>getSession</code> version with all parameters
* for details.
*
* <p>Used internally by HibernateTemplate, HibernateInterceptor, and
* HibernateTransactionManager. Can also be used directly in application code,
* e.g. in combination with HibernateInterceptor.
*
* @author Juergen Hoeller
* @since 1.2
* @see HibernateTemplate
* @see HibernateInterceptor
* @see HibernateTransactionManager
* @see org.springframework.transaction.jta.JtaTransactionManager
*/
public abstract class SessionFactoryUtils {
/**
* Order value for TransactionSynchronization objects that clean up Hibernate
* Sessions. Return DataSourceUtils.CONNECTION_SYNCHRONIZATION_ORDER - 100
* to execute Session cleanup before JDBC Connection cleanup, if any.
* @see org.springframework.jdbc.datasource.DataSourceUtils#CONNECTION_SYNCHRONIZATION_ORDER
*/
public static final int SESSION_SYNCHRONIZATION_ORDER =
DataSourceUtils.CONNECTION_SYNCHRONIZATION_ORDER - 100;
private static final Log logger = LogFactory.getLog(SessionFactoryUtils.class);
private static ThreadLocal deferredCloseHolder = new ThreadLocal();
/**
* Determine the DataSource of the given SessionFactory.
* @param sessionFactory the SessionFactory to check
* @return the DataSource, or <code>null</code> if none found
* @see org.hibernate.engine.SessionFactoryImplementor#getConnectionProvider
* @see LocalDataSourceConnectionProvider
*/
public static DataSource getDataSource(SessionFactory sessionFactory) {
if (sessionFactory instanceof SessionFactoryImplementor) {
ConnectionProvider cp = ((SessionFactoryImplementor) sessionFactory).getConnectionProvider();
if (cp instanceof LocalDataSourceConnectionProvider) {
return ((LocalDataSourceConnectionProvider) cp).getDataSource();
}
}
return null;
}
/**
* Create an appropriate SQLExceptionTranslator for the given SessionFactory.
* If a DataSource is found, a SQLErrorCodeSQLExceptionTranslator for the DataSource
* is created; else, a SQLStateSQLExceptionTranslator as fallback.
* @param sessionFactory the SessionFactory to create the translator for
* @return the SQLExceptionTranslator
* @see #getDataSource
* @see org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator
* @see org.springframework.jdbc.support.SQLStateSQLExceptionTranslator
*/
public static SQLExceptionTranslator newJdbcExceptionTranslator(SessionFactory sessionFactory) {
DataSource ds = getDataSource(sessionFactory);
if (ds != null) {
return new SQLErrorCodeSQLExceptionTranslator(ds);
}
return new SQLStateSQLExceptionTranslator();
}
/**
* Try to retrieve the JTA TransactionManager from the given SessionFactory
* and/or Session. Check the passed-in SessionFactory for implementing
* SessionFactoryImplementor (the usual case), falling back to the
* SessionFactory reference that the Session itself carries (for example,
* when using Hibernate's JCA Connector, i.e. JCASessionFactoryImpl).
* @param sessionFactory Hibernate SessionFactory
* @param session Hibernate Session (can also be <code>null</code>)
* @return the JTA TransactionManager, if any
* @see javax.transaction.TransactionManager
* @see SessionFactoryImplementor#getTransactionManager
* @see Session#getSessionFactory
* @see org.hibernate.impl.SessionFactoryImpl
* @see org.hibernate.jca.JCASessionFactoryImpl
*/
public static TransactionManager getJtaTransactionManager(SessionFactory sessionFactory, Session session) {
SessionFactoryImplementor sessionFactoryImpl = null;
if (sessionFactory instanceof SessionFactoryImplementor) {
sessionFactoryImpl = ((SessionFactoryImplementor) sessionFactory);
}
else if (session != null) {
SessionFactory internalFactory = session.getSessionFactory();
if (internalFactory instanceof SessionFactoryImplementor) {
sessionFactoryImpl = (SessionFactoryImplementor) internalFactory;
}
}
return (sessionFactoryImpl != null ? sessionFactoryImpl.getTransactionManager() : null);
}
/**
* Get a Hibernate Session for the given SessionFactory. Is aware of and will
* return any existing corresponding Session bound to the current thread, for
* example when using HibernateTransactionManager. Will create a new Session
* otherwise, if allowCreate is true.
* <p>This is the <code>getSession</code> method used by typical data access code,
* in combination with <code>releaseSession</code> called when done with
* the Session. Note that HibernateTemplate allows to write data access code
* without caring about such resource handling.
* <p>Supports synchronization with both Spring-managed JTA transactions
* (i.e. JtaTransactionManager) and non-Spring JTA transactions (i.e. plain JTA
* or EJB CMT). See the <code>getSession</code> version with all parameters
* for details.
* @param sessionFactory Hibernate SessionFactory to create the session with
* @param allowCreate if a non-transactional Session should be created when no
* transactional Session can be found for the current thread
* @return the Hibernate Session
* @throws DataAccessResourceFailureException if the Session couldn't be created
* @throws IllegalStateException if no thread-bound Session found and allowCreate false
* @see #getSession(SessionFactory, Interceptor, SQLExceptionTranslator)
* @see #releaseSession
* @see HibernateTemplate
*/
public static Session getSession(SessionFactory sessionFactory, boolean allowCreate)
throws DataAccessResourceFailureException, IllegalStateException {
try {
return doGetSession(sessionFactory, null, null, allowCreate);
}
catch (HibernateException ex) {
throw new DataAccessResourceFailureException("Could not open Hibernate Session", ex);
}
}
/**
* Get a Hibernate Session for the given SessionFactory. Is aware of and will
* return any existing corresponding Session bound to the current thread, for
* example when using HibernateTransactionManager. Will always create a new
* Session otherwise.
* <p>Supports synchronization with Spring-managed JTA transactions
* (i.e. JtaTransactionManager) via TransactionSynchronizationManager, to allow
* for transaction-scoped Hibernate Sessions and proper transactional handling
* of the JVM-level cache.
* <p>Supports synchronization with non-Spring JTA transactions (i.e. plain JTA
* or EJB CMT) via TransactionSynchronizationManager, to allow for
* transaction-scoped Hibernate Sessions without JtaTransactionManager.
* This only applies when a JTA TransactionManagerLookup is specified in the
* Hibernate configuration.
* <p>Supports setting a Session-level Hibernate entity interceptor that allows
* to inspect and change property values before writing to and reading from the
* database. Such an interceptor can also be set at the SessionFactory level
* (i.e. on LocalSessionFactoryBean), on HibernateTransactionManager, or on
* HibernateInterceptor/HibernateTemplate.
* @param sessionFactory Hibernate SessionFactory to create the session with
* @param entityInterceptor Hibernate entity interceptor, or <code>null</code> if none
* @param jdbcExceptionTranslator SQLExcepionTranslator to use for flushing the
* Session on transaction synchronization (can be <code>null</code>; only used when actually
* registering a transaction synchronization)
* @return the Hibernate Session
* @throws DataAccessResourceFailureException if the Session couldn't be created
* @see LocalSessionFactoryBean#setEntityInterceptor
* @see HibernateInterceptor#setEntityInterceptor
* @see HibernateTemplate#setEntityInterceptor
* @see HibernateTransactionManager
* @see org.springframework.transaction.jta.JtaTransactionManager
* @see org.springframework.transaction.support.TransactionSynchronizationManager
*/
public static Session getSession(
SessionFactory sessionFactory, Interceptor entityInterceptor,
SQLExceptionTranslator jdbcExceptionTranslator) throws DataAccessResourceFailureException {
try {
return doGetSession(sessionFactory, entityInterceptor, jdbcExceptionTranslator, true);
}
catch (HibernateException ex) {
throw new DataAccessResourceFailureException("Could not open Hibernate Session", ex);
}
}
/**
* Get a Hibernate Session for the given SessionFactory. Is aware of and will
* return any existing corresponding Session bound to the current thread, for
* example when using HibernateTransactionManager. Will create a new Session
* otherwise, if allowCreate is true.
* <p>Supports synchronization with both Spring-managed JTA transactions
* (i.e. JtaTransactionManager) and non-Spring JTA transactions (i.e. plain JTA
* or EJB CMT). See the <code>getSession</code> version with all parameters
* for details.
* <p>Throws the original HibernateException, in contrast to <code>getSession</code>.
* @param sessionFactory Hibernate SessionFactory to create the session with
* @param allowCreate if a non-transactional Session should be created when no
* transactional Session can be found for the current thread
* @return the Hibernate Session
* @throws HibernateException if the Session couldn't be created
* @throws IllegalStateException if no thread-bound Session found and allowCreate false
* @see #getSession(SessionFactory, Interceptor, SQLExceptionTranslator)
* @see #releaseSession
* @see HibernateTemplate
*/
public static Session doGetSession(SessionFactory sessionFactory, boolean allowCreate)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -