📄 sessionfactoryutils.java
字号:
* <code>Session.toString()</code> implementation is broken (and won't be fixed):
* it logs the toString representation of all persistent objects in the Session,
* which might lead to ConcurrentModificationExceptions if the persistent objects
* in turn refer to the Session (for example, for lazy loading).
* @param session the Hibernate Session to stringify
* @return the String representation of the given Session
*/
public static String toString(Session session) {
return session.getClass().getName() + "@" + Integer.toHexString(System.identityHashCode(session));
}
/**
* Return whether the given Hibernate Session is transactional, that is,
* bound to the current thread by Spring's transaction facilities.
* @param session the Hibernate Session to check
* @param sessionFactory Hibernate SessionFactory that the Session was created with
* (may be <code>null</code>)
* @return whether the Session is transactional
*/
public static boolean isSessionTransactional(Session session, SessionFactory sessionFactory) {
if (sessionFactory == null) {
return false;
}
SessionHolder sessionHolder =
(SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory);
return (sessionHolder != null && sessionHolder.containsSession(session));
}
/**
* 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
* (may be <code>null</code>)
* @see org.hibernate.Query#setTimeout
*/
public static void applyTransactionTimeout(Query query, SessionFactory sessionFactory) {
Assert.notNull(query, "No Query object specified");
if (sessionFactory != null) {
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
* @see org.hibernate.Criteria#setTimeout
*/
public static void applyTransactionTimeout(Criteria criteria, SessionFactory sessionFactory) {
Assert.notNull(criteria, "No Criteria object specified");
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 <code>org.springframework.dao</code> hierarchy.
* <p>Note that it is advisable to handle {@link org.hibernate.JDBCException}
* specifically by using a {@link org.springframework.jdbc.support.SQLExceptionTranslator}
* for the underlying SQLException.
* @param ex HibernateException that occured
* @return the corresponding DataAccessException instance
* @see HibernateAccessor#convertHibernateAccessException
* @see HibernateTransactionManager#convertHibernateAccessException
*/
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 StaleStateException) {
return new HibernateOptimisticLockingFailureException((StaleStateException) ex);
}
if (ex instanceof QueryException) {
return new HibernateQueryException((QueryException) ex);
}
if (ex instanceof PersistentObjectException) {
return new InvalidDataAccessApiUsageException(ex.getMessage(), ex);
}
if (ex instanceof TransientObjectException) {
return new InvalidDataAccessApiUsageException(ex.getMessage(), ex);
}
// fallback
return new HibernateSystemException(ex);
}
/**
* Determine whether deferred close is active for the current thread
* and the given SessionFactory.
* @param sessionFactory the Hibernate SessionFactory to check
* @return whether deferred close is active
*/
public static boolean isDeferredCloseActive(SessionFactory sessionFactory) {
Assert.notNull(sessionFactory, "No SessionFactory specified");
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
* {@link #processDeferredClose} call at a finishing point (like request completion).
* <p>Used by {@link org.springframework.orm.hibernate3.support.OpenSessionInViewFilter}
* and {@link org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor}
* when not configured for a single session.
* @param sessionFactory the Hibernate SessionFactory to initialize deferred close for
* @see #processDeferredClose
* @see #releaseSession
* @see org.springframework.orm.hibernate3.support.OpenSessionInViewFilter#setSingleSession
* @see org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor#setSingleSession
*/
public static void initDeferredClose(SessionFactory sessionFactory) {
Assert.notNull(sessionFactory, "No SessionFactory specified");
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, CollectionFactory.createLinkedSetIfPossible(4));
}
/**
* Process all Hibernate Sessions that have been registered for deferred close
* for the given SessionFactory.
* @param sessionFactory the Hibernate SessionFactory to process deferred close for
* @see #initDeferredClose
* @see #releaseSession
*/
public static void processDeferredClose(SessionFactory sessionFactory) {
Assert.notNull(sessionFactory, "No SessionFactory specified");
Map holderMap = (Map) deferredCloseHolder.get();
if (holderMap == null || !holderMap.containsKey(sessionFactory)) {
throw new IllegalStateException("Deferred close not active for SessionFactory [" + sessionFactory + "]");
}
logger.debug("Processing deferred close of Hibernate Sessions");
Set sessions = (Set) holderMap.remove(sessionFactory);
for (Iterator it = sessions.iterator(); it.hasNext();) {
doClose((Session) it.next());
}
if (holderMap.isEmpty()) {
deferredCloseHolder.set(null);
}
}
/**
* Close the given Session, created via the given factory,
* if it isn't bound to the thread.
* @deprecated in favor of releaseSession
* @see #releaseSession
*/
public static void closeSessionIfNecessary(Session session, SessionFactory sessionFactory) {
releaseSession(session, sessionFactory);
}
/**
* Close the given Session, created via the given factory,
* if it is not managed externally (i.e. not bound to the thread).
* @param session the Hibernate Session to close (may be <code>null</code>)
* @param sessionFactory Hibernate SessionFactory that the Session was created with
* (may be <code>null</code>)
*/
public static void releaseSession(Session session, SessionFactory sessionFactory) {
if (session == null) {
return;
}
// Only close non-transactional Sessions.
if (!isSessionTransactional(session, sessionFactory)) {
closeSessionOrRegisterDeferredClose(session, sessionFactory);
}
}
/**
* Close the given Session or register it for deferred close.
* @param session the Hibernate Session to close
* @param sessionFactory Hibernate SessionFactory that the Session was created with
* (may be <code>null</code>)
* @see #initDeferredClose
* @see #processDeferredClose
*/
private static void closeSessionOrRegisterDeferredClose(Session session, SessionFactory sessionFactory) {
Map holderMap = (Map) deferredCloseHolder.get();
if (holderMap != null && sessionFactory != null && holderMap.containsKey(sessionFactory)) {
logger.debug("Registering Hibernate Session for deferred close");
// Switch Session to FlushMode.NEVER for remaining lifetime.
session.setFlushMode(FlushMode.NEVER);
Set sessions = (Set) holderMap.get(sessionFactory);
sessions.add(session);
}
else {
doClose(session);
}
}
/**
* Perform actual closing of the Hibernate Session,
* catching and logging any cleanup exceptions thrown.
* @param session the Hibernate Session to close (may be <code>null</code>)
* @see org.hibernate.Session#close()
*/
private static void doClose(Session session) {
if (session != null) {
logger.debug("Closing Hibernate Session");
try {
session.close();
}
catch (HibernateException ex) {
logger.debug("Could not close Hibernate Session", ex);
}
catch (Throwable ex) {
logger.debug("Unexpected exception on closing Hibernate Session", ex);
}
}
}
/**
* Callback for resource cleanup at the end of a Spring-managed JTA transaction,
* i.e. when participating in a JtaTransactionManager transaction.
* @see org.springframework.transaction.jta.JtaTransactionManager
*/
private static class SpringSessionSynchronization implements TransactionSynchronization, Ordered {
private final SessionHolder sessionHolder;
private final SessionFactory sessionFactory;
private final SQLExceptionTranslator jdbcExceptionTranslator;
private final boolean newSession;
/**
* Whether Hibernate has a looked-up JTA TransactionManager that it will
* automatically register CacheSynchronizations with on Session connect.
*/
private boolean hibernateTransactionCompletion = false;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -