Instantly share code, notes, and snippets.

Embed
What would you like to do?
HibernateSessionAdvice
public class HibernateSessionAdvice {
private static Log logger = LogFactory.getLog(HibernateSessionAdvice.class);
public static final String DEFAULT_SESSION_FACTORY_BEAN_NAME = "sessionFactory";
private String sessionFactoryBeanName = DEFAULT_SESSION_FACTORY_BEAN_NAME;
private boolean singleSession = true;
private FlushMode flushMode = FlushMode.MANUAL;
private SessionFactory sessionFactory;
private ThreadLocal<Boolean> participate;
public HibernateSessionAdvice(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
this.participate = new ThreadLocal<Boolean>();
this.participate.set(false);
}
public void openSession() {
participate.set(false);
if (isSingleSession()) {
// single session mode
if (TransactionSynchronizationManager.hasResource(sessionFactory)) {
// Do not modify the Session: just set the participate flag.
participate.set(true);
} else {
logger.debug("Opening single Hibernate Session in OpenSessionInViewFilter");
Session 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.set(true);
} else {
SessionFactoryUtils.initDeferredClose(sessionFactory);
}
}
}
public void closeSession() {
if (!participate.get()) {
if (isSingleSession()) {
// single session mode
SessionHolder sessionHolder = (SessionHolder) TransactionSynchronizationManager
.unbindResource(sessionFactory);
logger.debug("Closing single Hibernate Session in OpenSessionInViewFilter");
closeSession(sessionHolder.getSession(), sessionFactory);
} else {
// deferred close mode
SessionFactoryUtils.processDeferredClose(sessionFactory);
}
}
}
/**
* Set the bean name of the SessionFactory to fetch from Spring's root
* application context. Default is "sessionFactory".
*
* @see #DEFAULT_SESSION_FACTORY_BEAN_NAME
*/
public void setSessionFactoryBeanName(String sessionFactoryBeanName) {
this.sessionFactoryBeanName = sessionFactoryBeanName;
}
/**
* Return the bean name of the SessionFactory to fetch from Spring's root
* application context.
*/
protected String getSessionFactoryBeanName() {
return this.sessionFactoryBeanName;
}
/**
* Set whether to use a single session for each request. Default is "true".
* <p>
* 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;
}
/**
* Return whether to use a single session for each request.
*/
protected boolean isSingleSession() {
return this.singleSession;
}
/**
* Specify the Hibernate FlushMode to apply to this filter's
* {@link org.hibernate.Session}. Only applied in single session mode.
* <p>
* Can be populated with the corresponding constant name in XML bean
* definitions: e.g. "AUTO".
* <p>
* The default is "MANUAL". Specify "AUTO" if you intend to use this filter
* without service layer transactions.
*
* @see org.hibernate.Session#setFlushMode
* @see org.hibernate.FlushMode#MANUAL
* @see org.hibernate.FlushMode#AUTO
*/
public void setFlushMode(FlushMode flushMode) {
this.flushMode = flushMode;
}
/**
* Return the Hibernate FlushMode that this filter applies to its
* {@link org.hibernate.Session} (in single session mode).
*/
protected FlushMode getFlushMode() {
return this.flushMode;
}
/**
* Get a Session for the SessionFactory that this filter uses. Note that
* this just applies in single session mode!
* <p>
* The default implementation delegates to the
* <code>SessionFactoryUtils.getSession</code> method and sets the
* <code>Session</code>'s flush mode to "MANUAL".
* <p>
* 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#MANUAL
*/
protected Session getSession(SessionFactory sessionFactory)
throws DataAccessResourceFailureException {
Session session = SessionFactoryUtils.getSession(sessionFactory, true);
FlushMode flushMode = getFlushMode();
if (flushMode != null) {
session.setFlushMode(flushMode);
}
return session;
}
/**
* Close the given Session. Note that this just applies in single session
* mode!
* <p>
* 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.closeSession(session);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment