com.discursive.dao.generic.hibernate.OpenSessionInterceptor Maven / Gradle / Ivy
Show all versions of generic-dao Show documentation
package com.discursive.dao.generic.hibernate;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.log4j.Logger;
import org.hibernate.FlushMode;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.orm.hibernate3.SessionFactoryUtils;
import org.springframework.orm.hibernate3.SessionHolder;
import org.springframework.transaction.support.TransactionSynchronizationManager;
public class OpenSessionInterceptor implements MethodInterceptor {
public static final Logger logger = Logger.getLogger( OpenSessionInterceptor.class );
private SessionFactory sessionFactory;
private boolean singleSession = true;
/**
* Get a Session for the SessionFactory that this filter uses.
* Note that this just applies in single session mode!
* The default implementation delegates to SessionFactoryUtils'
* getSession method and sets the Session's flushMode to NEVER.
*
Can be overridden in subclasses for creating a Session with a custom
* entity interceptor or JDBC exception translator.
* @param sessionFactory the SessionFactory that this filter uses
* @return the Session to use
* @throws DataAccessResourceFailureException if the Session could not be created
* @see org.springframework.orm.hibernate3.SessionFactoryUtils#getSession(SessionFactory, boolean)
* @see org.hibernate.FlushMode#NEVER
*/
@SuppressWarnings("deprecation")
protected Session getSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException {
Session session = SessionFactoryUtils.getSession(sessionFactory, true);
//session.setFlushMode(FlushMode.NEVER);
session.setFlushMode(FlushMode.MANUAL);
return session;
}
/**
* Close the given Session.
* Note that this just applies in single session mode!
*
The default implementation delegates to SessionFactoryUtils'
* releaseSession method.
*
Can be overridden in subclasses, e.g. for flushing the Session before
* closing it. See class-level javadoc for a discussion of flush handling.
* Note that you should also override getSession accordingly, to set
* the flush mode to something else than NEVER.
* @param session the Session used for filtering
* @param sessionFactory the SessionFactory that this filter uses
*/
protected void closeSession(Session session, SessionFactory sessionFactory) {
SessionFactoryUtils.releaseSession(session, sessionFactory);
}
public Object invoke(MethodInvocation invocation) throws Throwable {
Object returnObject;
Session session = null;
boolean participate = false;
if (singleSession) {
// single session mode
if (TransactionSynchronizationManager.hasResource(sessionFactory)) {
// Do not modify the Session: just set the participate flag.
participate = true;
}
else {
logger.debug("Opening single Hibernate Session in OpenSessionInViewFilter");
session = getSession(sessionFactory);
TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));
}
}
else {
// deferred close mode
if (SessionFactoryUtils.isDeferredCloseActive(sessionFactory)) {
// Do not modify deferred close: just set the participate flag.
participate = true;
}
else {
SessionFactoryUtils.initDeferredClose(sessionFactory);
}
}
try {
returnObject = invocation.proceed();
}
finally {
if (!participate) {
if (singleSession) {
// single session mode
TransactionSynchronizationManager.unbindResource(sessionFactory);
logger.debug("Closing single Hibernate Session in OpenSessionInViewFilter");
try {
closeSession(session, sessionFactory);
}
catch (RuntimeException ex) {
logger.error("Unexpected exception on closing Hibernate Session", ex);
}
}
else {
// deferred close mode
SessionFactoryUtils.processDeferredClose(sessionFactory);
}
}
}
return returnObject;
}
@Required
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
/**
* Set whether to use a single session for each request. Default is "true".
*
If set to false, each data access operation or transaction will use
* its own session (like without Open Session in View). Each of those
* sessions will be registered for deferred close, though, actually
* processed at request completion.
* @see SessionFactoryUtils#initDeferredClose
* @see SessionFactoryUtils#processDeferredClose
*/
public void setSingleSession(boolean singleSession) {
this.singleSession = singleSession;
}
}