Introduced OpenSessionInterceptor as a streamlined alternative to HibernateInterceptor
Issue: SPR-9028
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -16,10 +16,17 @@
|
||||
|
||||
package org.springframework.orm.hibernate4.support;
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.hibernate.FlushMode;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.SessionFactory;
|
||||
|
||||
import org.springframework.dao.DataAccessResourceFailureException;
|
||||
import org.springframework.orm.hibernate4.SessionFactoryUtils;
|
||||
import org.springframework.orm.hibernate4.SessionHolder;
|
||||
@@ -30,12 +37,6 @@ import org.springframework.web.context.request.async.WebAsyncUtils;
|
||||
import org.springframework.web.context.support.WebApplicationContextUtils;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Servlet 2.3 Filter that binds a Hibernate Session to the thread for the entire
|
||||
* processing of the request. Intended for the "Open Session in View" pattern,
|
||||
@@ -70,8 +71,10 @@ import java.io.IOException;
|
||||
* @since 3.1
|
||||
* @see #lookupSessionFactory
|
||||
* @see OpenSessionInViewInterceptor
|
||||
* @see OpenSessionInterceptor
|
||||
* @see org.springframework.orm.hibernate4.HibernateTransactionManager
|
||||
* @see org.springframework.transaction.support.TransactionSynchronizationManager
|
||||
* @see org.hibernate.SessionFactory#getCurrentSession()
|
||||
*/
|
||||
public class OpenSessionInViewFilter extends OncePerRequestFilter {
|
||||
|
||||
@@ -190,9 +193,8 @@ public class OpenSessionInViewFilter extends OncePerRequestFilter {
|
||||
|
||||
/**
|
||||
* Open a Session for the SessionFactory that this filter uses.
|
||||
* <p>The default implementation delegates to the
|
||||
* {@code SessionFactory.openSession} method and
|
||||
* sets the {@code Session}'s flush mode to "MANUAL".
|
||||
* <p>The default implementation delegates to the {@link SessionFactory#openSession}
|
||||
* method and sets the {@link Session}'s flush mode to "MANUAL".
|
||||
* @param sessionFactory the SessionFactory that this filter uses
|
||||
* @return the Session to use
|
||||
* @throws DataAccessResourceFailureException if the Session could not be created
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2014 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.
|
||||
@@ -60,8 +60,10 @@ import org.springframework.web.context.request.async.WebAsyncUtils;
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.1
|
||||
* @see OpenSessionInViewFilter
|
||||
* @see OpenSessionInterceptor
|
||||
* @see org.springframework.orm.hibernate4.HibernateTransactionManager
|
||||
* @see org.springframework.transaction.support.TransactionSynchronizationManager
|
||||
* @see org.hibernate.SessionFactory#getCurrentSession()
|
||||
*/
|
||||
public class OpenSessionInViewInterceptor implements AsyncWebRequestInterceptor {
|
||||
|
||||
@@ -79,16 +81,14 @@ public class OpenSessionInViewInterceptor implements AsyncWebRequestInterceptor
|
||||
|
||||
|
||||
/**
|
||||
* Set the Hibernate SessionFactory that should be used to create
|
||||
* Hibernate Sessions.
|
||||
* Set the Hibernate SessionFactory that should be used to create Hibernate Sessions.
|
||||
*/
|
||||
public void setSessionFactory(SessionFactory sessionFactory) {
|
||||
this.sessionFactory = sessionFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Hibernate SessionFactory that should be used to create
|
||||
* Hibernate Sessions.
|
||||
* Return the Hibernate SessionFactory that should be used to create Hibernate Sessions.
|
||||
*/
|
||||
public SessionFactory getSessionFactory() {
|
||||
return this.sessionFactory;
|
||||
@@ -173,9 +173,8 @@ public class OpenSessionInViewInterceptor implements AsyncWebRequestInterceptor
|
||||
|
||||
/**
|
||||
* Open a Session for the SessionFactory that this interceptor uses.
|
||||
* <p>The default implementation delegates to the
|
||||
* {@code SessionFactory.openSession} method and
|
||||
* sets the {@code Session}'s flush mode to "MANUAL".
|
||||
* <p>The default implementation delegates to the {@link SessionFactory#openSession}
|
||||
* method and sets the {@link Session}'s flush mode to "MANUAL".
|
||||
* @return the Session to use
|
||||
* @throws DataAccessResourceFailureException if the Session could not be created
|
||||
* @see org.hibernate.FlushMode#MANUAL
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright 2002-2014 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.hibernate4.support;
|
||||
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.hibernate.FlushMode;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.SessionFactory;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.dao.DataAccessResourceFailureException;
|
||||
import org.springframework.orm.hibernate4.SessionFactoryUtils;
|
||||
import org.springframework.orm.hibernate4.SessionHolder;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
|
||||
/**
|
||||
* Simple AOP Alliance {@link MethodInterceptor} implementation that binds a new
|
||||
* Hibernate {@link Session} for each method invocation, if none bound before.
|
||||
*
|
||||
* <p>This is a simple Hibernate Session scoping interceptor along the lines of
|
||||
* {@link OpenSessionInViewInterceptor}, just for use with AOP setup instead of
|
||||
* MVC setup. It opens a new {@link Session} with flush mode "MANUAL" since the
|
||||
* Session is only meant for reading, except when participating in a transaction.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 4.0.2
|
||||
* @see OpenSessionInViewInterceptor
|
||||
* @see OpenSessionInViewFilter
|
||||
* @see org.springframework.orm.hibernate4.HibernateTransactionManager
|
||||
* @see org.springframework.transaction.support.TransactionSynchronizationManager
|
||||
* @see org.hibernate.SessionFactory#getCurrentSession()
|
||||
*/
|
||||
public class OpenSessionInterceptor implements MethodInterceptor, InitializingBean {
|
||||
|
||||
private SessionFactory sessionFactory;
|
||||
|
||||
|
||||
/**
|
||||
* Set the Hibernate SessionFactory that should be used to create Hibernate Sessions.
|
||||
*/
|
||||
public void setSessionFactory(SessionFactory sessionFactory) {
|
||||
this.sessionFactory = sessionFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Hibernate SessionFactory that should be used to create Hibernate Sessions.
|
||||
*/
|
||||
public SessionFactory getSessionFactory() {
|
||||
return this.sessionFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() {
|
||||
if (getSessionFactory() == null) {
|
||||
throw new IllegalArgumentException("Property 'sessionFactory' is required");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object invoke(MethodInvocation invocation) throws Throwable {
|
||||
SessionFactory sf = getSessionFactory();
|
||||
if (!TransactionSynchronizationManager.hasResource(sf)) {
|
||||
// New Session to be bound for the current method's scope...
|
||||
Session session = openSession();
|
||||
try {
|
||||
TransactionSynchronizationManager.bindResource(sf, new SessionHolder(session));
|
||||
return invocation.proceed();
|
||||
}
|
||||
finally {
|
||||
SessionFactoryUtils.closeSession(session);
|
||||
TransactionSynchronizationManager.unbindResource(sf);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Pre-bound Session found -> simply proceed.
|
||||
return invocation.proceed();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a Session for the SessionFactory that this interceptor uses.
|
||||
* <p>The default implementation delegates to the {@link SessionFactory#openSession}
|
||||
* method and sets the {@link Session}'s flush mode to "MANUAL".
|
||||
* @return the Session to use
|
||||
* @throws DataAccessResourceFailureException if the Session could not be created
|
||||
* @see org.hibernate.FlushMode#MANUAL
|
||||
*/
|
||||
protected Session openSession() throws DataAccessResourceFailureException {
|
||||
try {
|
||||
Session session = getSessionFactory().openSession();
|
||||
session.setFlushMode(FlushMode.MANUAL);
|
||||
return session;
|
||||
}
|
||||
catch (HibernateException ex) {
|
||||
throw new DataAccessResourceFailureException("Could not open Hibernate Session", ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user