📄 sessionfactoryutils.java
字号:
* @param allowSynchronization if a new Hibernate Session is supposed to be
* registered with transaction synchronization (if synchronization is active)
* @param allowCreate if a new Session should be created if no thread-bound found
* @return the Hibernate Session
* @throws DataAccessResourceFailureException if the Session couldn't be created
* @throws IllegalStateException if no thread-bound Session found and allowCreate false
*/
private static Session getSession(
SessionFactory sessionFactory, Interceptor entityInterceptor,
SQLExceptionTranslator jdbcExceptionTranslator, boolean allowSynchronization, boolean allowCreate)
throws DataAccessResourceFailureException, IllegalStateException {
SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory);
if (sessionHolder != null) {
// pre-bound Hibernate Session
if (TransactionSynchronizationManager.isSynchronizationActive()) {
// Spring transaction management is active ->
// register pre-bound Session with it for transactional flushing.
if (allowSynchronization && !sessionHolder.isSynchronizedWithTransaction()) {
logger.debug("Registering Spring transaction synchronization for existing Hibernate session");
TransactionSynchronizationManager.registerSynchronization(
new SpringSessionSynchronization(sessionHolder, sessionFactory, jdbcExceptionTranslator, false));
sessionHolder.setSynchronizedWithTransaction(true);
FlushMode flushMode = sessionHolder.getSession().getFlushMode();
if (FlushMode.NEVER.equals(flushMode)) {
sessionHolder.getSession().setFlushMode(FlushMode.AUTO);
sessionHolder.setPreviousFlushMode(flushMode);
}
}
return sessionHolder.getSession();
}
else {
// no Spring transaction management active
TransactionManager jtaTm = getJtaTransactionManager(sessionFactory, sessionHolder.getAnySession());
if (jtaTm != null) {
// Check whether JTA transaction management is active ->
// fetch pre-bound Session for the current JTA transaction, if any.
// (just necessary for JTA transaction suspension, with an individual
// Hibernate Session per currently active/suspended transaction)
try {
int jtaStatus = jtaTm.getStatus();
if (jtaStatus == Status.STATUS_ACTIVE || jtaStatus == Status.STATUS_MARKED_ROLLBACK) {
// look for transaction-specific Session
Session session = sessionHolder.getSession(jtaTm.getTransaction());
if (session != null) {
return session;
}
}
else {
// no transaction active -> simply return default thread-bound Session
return sessionHolder.getSession();
}
}
catch (SystemException ex) {
throw new DataAccessResourceFailureException("Could not check JTA transaction", ex);
}
}
else {
// no JTA TransactionManager -> simply return default thread-bound Session
return sessionHolder.getSession();
}
}
}
if (!allowCreate) {
throw new IllegalStateException("No Hibernate session bound to thread, " +
"and configuration does not allow creation of new one here");
}
logger.debug("Opening Hibernate session");
try {
Session session = (entityInterceptor != null ?
sessionFactory.openSession(entityInterceptor) : sessionFactory.openSession());
if (allowSynchronization) {
// Use same Session for further Hibernate actions within the transaction.
// Thread object will get removed by synchronization at transaction completion.
if (TransactionSynchronizationManager.isSynchronizationActive()) {
// We're within a Spring-managed transaction, possibly from JtaTransactionManager.
logger.debug("Registering Spring transaction synchronization for new Hibernate session");
sessionHolder = new SessionHolder(session);
sessionHolder.setSynchronizedWithTransaction(true);
TransactionSynchronizationManager.registerSynchronization(
new SpringSessionSynchronization(sessionHolder, sessionFactory, jdbcExceptionTranslator, true));
TransactionSynchronizationManager.bindResource(sessionFactory, sessionHolder);
}
else {
// JTA synchronization is only possible with a javax.transaction.TransactionManager.
// We'll check the Hibernate SessionFactory: If a TransactionManagerLookup is specified
// in Hibernate configuration, it will contain a TransactionManager reference.
TransactionManager jtaTm = getJtaTransactionManager(sessionFactory, session);
if (jtaTm != null) {
try {
int jtaStatus = jtaTm.getStatus();
if (jtaStatus == Status.STATUS_ACTIVE || jtaStatus == Status.STATUS_MARKED_ROLLBACK) {
logger.debug("Registering JTA transaction synchronization for new Hibernate session");
javax.transaction.Transaction jtaTx = jtaTm.getTransaction();
boolean newHolder = false;
// register with existing SessionHolder or create a new one
if (sessionHolder == null) {
sessionHolder = new SessionHolder(jtaTx, session);
sessionHolder.setSynchronizedWithTransaction(true);
newHolder = true;
}
else {
sessionHolder.addSession(jtaTx, session);
}
jtaTx.registerSynchronization(
new JtaSessionSynchronization(
new SpringSessionSynchronization(
sessionHolder, sessionFactory, jdbcExceptionTranslator, true),
jtaTm));
if (newHolder) {
TransactionSynchronizationManager.bindResource(sessionFactory, sessionHolder);
}
}
}
catch (Exception ex) {
throw new DataAccessResourceFailureException(
"Could not register synchronization with JTA TransactionManager", ex);
}
}
}
}
return session;
}
catch (JDBCException ex) {
// SQLException underneath
throw new DataAccessResourceFailureException(
"Could not open Hibernate session", ex.getSQLException());
}
catch (HibernateException ex) {
throw new DataAccessResourceFailureException("Could not open Hibernate session", ex);
}
}
/**
* Apply the current transaction timeout, if any, to the given
* Hibernate Query object.
* @param query the Hibernate Query object
* @param sessionFactory Hibernate SessionFactory that the Query was created for
*/
public static void applyTransactionTimeout(Query query, SessionFactory sessionFactory) {
SessionHolder sessionHolder =
(SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory);
if (sessionHolder != null && sessionHolder.hasTimeout()) {
query.setTimeout(sessionHolder.getTimeToLiveInSeconds());
}
}
/**
* Apply the current transaction timeout, if any, to the given
* Hibernate Criteria object.
* @param criteria the Hibernate Criteria object
* @param sessionFactory Hibernate SessionFactory that the Criteria was created for
*/
public static void applyTransactionTimeout(Criteria criteria, SessionFactory sessionFactory) {
SessionHolder sessionHolder =
(SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory);
if (sessionHolder != null && sessionHolder.hasTimeout()) {
criteria.setTimeout(sessionHolder.getTimeToLiveInSeconds());
}
}
/**
* Convert the given HibernateException to an appropriate exception from the
* org.springframework.dao hierarchy. Note that it is advisable to handle
* JDBCException specifically by using an SQLExceptionTranslator for the
* underlying SQLException.
* @param ex HibernateException that occured
* @return the corresponding DataAccessException instance
* @see HibernateAccessor#convertHibernateAccessException
* @see HibernateAccessor#convertJdbcAccessException
* @see HibernateTransactionManager#convertHibernateAccessException
* @see HibernateTransactionManager#convertJdbcAccessException
* @see net.sf.hibernate.JDBCException#getSQLException
* @see org.springframework.jdbc.support.SQLExceptionTranslator
*/
public static DataAccessException convertHibernateAccessException(HibernateException ex) {
if (ex instanceof JDBCException) {
// SQLException during Hibernate access: only passed in here from custom code,
// as HibernateTemplate etc will use SQLExceptionTranslator-based handling
return new HibernateJdbcException((JDBCException) ex);
}
if (ex instanceof UnresolvableObjectException) {
return new HibernateObjectRetrievalFailureException((UnresolvableObjectException) ex);
}
if (ex instanceof ObjectNotFoundException) {
return new HibernateObjectRetrievalFailureException((ObjectNotFoundException) ex);
}
if (ex instanceof ObjectDeletedException) {
return new HibernateObjectRetrievalFailureException((ObjectDeletedException) ex);
}
if (ex instanceof WrongClassException) {
return new HibernateObjectRetrievalFailureException((WrongClassException) ex);
}
if (ex instanceof StaleObjectStateException) {
return new HibernateOptimisticLockingFailureException((StaleObjectStateException) ex);
}
if (ex instanceof QueryException) {
return new HibernateQueryException((QueryException) ex);
}
if (ex instanceof PersistentObjectException) {
return new InvalidDataAccessApiUsageException(ex.getMessage());
}
if (ex instanceof TransientObjectException) {
return new InvalidDataAccessApiUsageException(ex.getMessage());
}
// fallback
return new HibernateSystemException(ex);
}
/**
* Return if deferred close is active for the current thread
* and the given SessionFactory.
* @param sessionFactory Hibernate SessionFactory
*/
public static boolean isDeferredCloseActive(SessionFactory sessionFactory) {
Map holderMap = (Map) deferredCloseHolder.get();
return (holderMap != null && holderMap.containsKey(sessionFactory));
}
/**
* Initialize deferred close for the current thread and the given SessionFactory.
* Sessions will not be actually closed on close calls then, but rather at a
* processDeferredClose call at a finishing point (like request completion).
* <p>Used by OpenSessionInViewFilter and OpenSessionInViewInterceptor
* when not configured for a single session.
* @param sessionFactory Hibernate SessionFactory
* @see #processDeferredClose
* @see #closeSessionIfNecessary
* @see org.springframework.orm.hibernate.support.OpenSessionInViewFilter#setSingleSession
* @see org.springframework.orm.hibernate.support.OpenSessionInViewInterceptor#setSingleSession
*/
public static void initDeferredClose(SessionFactory sessionFactory) {
logger.debug("Initializing deferred close of Hibernate sessions");
Map holderMap = (Map) deferredCloseHolder.get();
if (holderMap == null) {
holderMap = new HashMap();
deferredCloseHolder.set(holderMap);
}
holderMap.put(sessionFactory, new HashSet());
}
/**
* Process Sessions that have been registered for deferred close
* for the given SessionFactory.
* @param sessionFactory Hibernate SessionFactory
* @see #initDeferredClose
* @see #closeSessionIfNecessary
*/
public static void processDeferredClose(SessionFactory sessionFactory) {
Map holderMap = (Map) deferredCloseHolder.get();
if (holderMap == null || !holderMap.containsKey(sessionFactory)) {
throw new IllegalStateException("Deferred close not active for SessionFactory [" + sessionFactory + "]");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -