Introduced OpenSessionInterceptor as a streamlined alternative to HibernateInterceptor
Issue: SPR-9028
This commit is contained in:
@@ -72,6 +72,8 @@ import org.springframework.transaction.support.TransactionSynchronizationManager
|
||||
* native Hibernate API usage within transactions, in combination with a general
|
||||
* {@link org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor}.
|
||||
* Note: This class does not have an equivalent replacement in {@code orm.hibernate4}.
|
||||
* If you desperately need a scoped Session bound through AOP, consider the newly
|
||||
* introduced {@link org.springframework.orm.hibernate3.support.OpenSessionInterceptor}.
|
||||
*/
|
||||
@Deprecated
|
||||
public class HibernateInterceptor extends HibernateAccessor implements MethodInterceptor {
|
||||
|
||||
@@ -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.
|
||||
@@ -220,8 +220,7 @@ public abstract class SessionFactoryUtils {
|
||||
* <p>Supports setting a Session-level Hibernate entity interceptor that allows
|
||||
* to inspect and change property values before writing to and reading from the
|
||||
* database. Such an interceptor can also be set at the SessionFactory level
|
||||
* (i.e. on LocalSessionFactoryBean), on HibernateTransactionManager, or on
|
||||
* HibernateInterceptor/HibernateTemplate.
|
||||
* (i.e. on LocalSessionFactoryBean), on HibernateTransactionManager, etc.
|
||||
* @param sessionFactory Hibernate SessionFactory to create the session with
|
||||
* @param entityInterceptor Hibernate entity interceptor, or {@code null} if none
|
||||
* @param jdbcExceptionTranslator SQLExcepionTranslator to use for flushing the
|
||||
@@ -230,7 +229,6 @@ public abstract class SessionFactoryUtils {
|
||||
* @return the Hibernate Session
|
||||
* @throws DataAccessResourceFailureException if the Session couldn't be created
|
||||
* @see LocalSessionFactoryBean#setEntityInterceptor
|
||||
* @see HibernateInterceptor#setEntityInterceptor
|
||||
* @see HibernateTemplate#setEntityInterceptor
|
||||
*/
|
||||
public static Session getSession(
|
||||
@@ -377,8 +375,8 @@ public abstract class SessionFactoryUtils {
|
||||
* @throws DataAccessResourceFailureException if the Session couldn't be created
|
||||
*/
|
||||
private static Session getJtaSynchronizedSession(
|
||||
SessionHolder sessionHolder, SessionFactory sessionFactory,
|
||||
SQLExceptionTranslator jdbcExceptionTranslator) throws DataAccessResourceFailureException {
|
||||
SessionHolder sessionHolder, SessionFactory sessionFactory,
|
||||
SQLExceptionTranslator jdbcExceptionTranslator) throws DataAccessResourceFailureException {
|
||||
|
||||
// JTA synchronization is only possible with a javax.transaction.TransactionManager.
|
||||
// We'll check the Hibernate SessionFactory: If a TransactionManagerLookup is specified
|
||||
|
||||
@@ -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.
|
||||
@@ -17,7 +17,6 @@
|
||||
package org.springframework.orm.hibernate3.support;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
@@ -26,13 +25,15 @@ import javax.servlet.http.HttpServletResponse;
|
||||
import org.hibernate.FlushMode;
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.SessionFactory;
|
||||
|
||||
import org.springframework.dao.DataAccessResourceFailureException;
|
||||
import org.springframework.orm.hibernate3.SessionFactoryUtils;
|
||||
import org.springframework.orm.hibernate3.SessionHolder;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.context.WebApplicationContext;
|
||||
import org.springframework.web.context.request.async.*;
|
||||
import org.springframework.web.context.request.async.WebAsyncManager;
|
||||
import org.springframework.web.context.request.async.WebAsyncUtils;
|
||||
import org.springframework.web.context.support.WebApplicationContextUtils;
|
||||
import org.springframework.web.filter.OncePerRequestFilter;
|
||||
|
||||
@@ -87,10 +88,11 @@ import org.springframework.web.filter.OncePerRequestFilter;
|
||||
* @see #setFlushMode
|
||||
* @see #lookupSessionFactory
|
||||
* @see OpenSessionInViewInterceptor
|
||||
* @see org.springframework.orm.hibernate3.HibernateInterceptor
|
||||
* @see OpenSessionInterceptor
|
||||
* @see org.springframework.orm.hibernate3.HibernateTransactionManager
|
||||
* @see org.springframework.orm.hibernate3.SessionFactoryUtils#getSession
|
||||
* @see org.springframework.transaction.support.TransactionSynchronizationManager
|
||||
* @see org.hibernate.SessionFactory#getCurrentSession()
|
||||
*/
|
||||
public class OpenSessionInViewFilter extends OncePerRequestFilter {
|
||||
|
||||
@@ -165,7 +167,7 @@ public class OpenSessionInViewFilter extends OncePerRequestFilter {
|
||||
}
|
||||
|
||||
/**
|
||||
* The default value is "false" so that the filter may re-bind the opened
|
||||
* Returns "false" so that the filter may re-bind the opened Hibernate
|
||||
* {@code Session} to each asynchronously dispatched thread and postpone
|
||||
* closing it until the very last asynchronous dispatch.
|
||||
*/
|
||||
|
||||
@@ -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.
|
||||
@@ -18,6 +18,7 @@ package org.springframework.orm.hibernate3.support;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.Session;
|
||||
|
||||
import org.springframework.dao.DataAccessException;
|
||||
import org.springframework.orm.hibernate3.HibernateAccessor;
|
||||
import org.springframework.orm.hibernate3.SessionFactoryUtils;
|
||||
@@ -85,10 +86,11 @@ import org.springframework.web.context.request.async.WebAsyncUtils;
|
||||
* @see #setSingleSession
|
||||
* @see #setFlushMode
|
||||
* @see OpenSessionInViewFilter
|
||||
* @see org.springframework.orm.hibernate3.HibernateInterceptor
|
||||
* @see OpenSessionInterceptor
|
||||
* @see org.springframework.orm.hibernate3.HibernateTransactionManager
|
||||
* @see org.springframework.orm.hibernate3.SessionFactoryUtils#getSession
|
||||
* @see org.springframework.transaction.support.TransactionSynchronizationManager
|
||||
* @see org.hibernate.SessionFactory#getCurrentSession()
|
||||
*/
|
||||
public class OpenSessionInViewInterceptor extends HibernateAccessor implements AsyncWebRequestInterceptor {
|
||||
|
||||
@@ -142,10 +144,9 @@ public class OpenSessionInViewInterceptor extends HibernateAccessor implements A
|
||||
*/
|
||||
@Override
|
||||
public void preHandle(WebRequest request) throws DataAccessException {
|
||||
|
||||
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
|
||||
String participateAttributeName = getParticipateAttributeName();
|
||||
|
||||
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
|
||||
if (asyncManager.hasConcurrentResult()) {
|
||||
if (applySessionBindingInterceptor(asyncManager, participateAttributeName)) {
|
||||
return;
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* 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.hibernate3.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.hibernate3.SessionFactoryUtils;
|
||||
import org.springframework.orm.hibernate3.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.
|
||||
*
|
||||
* <p>Note: This can serve as a streamlined alternative to the outdated
|
||||
* {@link org.springframework.orm.hibernate3.HibernateInterceptor}, providing
|
||||
* plain Session binding without any automatic exception translation or the like.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 4.0.2
|
||||
* @see OpenSessionInViewInterceptor
|
||||
* @see OpenSessionInViewFilter
|
||||
* @see org.springframework.orm.hibernate3.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