diff --git a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/support/OpenSessionInViewFilter.java b/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/support/OpenSessionInViewFilter.java index 6ab5668293..e266faa299 100644 --- a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/support/OpenSessionInViewFilter.java +++ b/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/support/OpenSessionInViewFilter.java @@ -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. - *
The default implementation delegates to the - * {@code SessionFactory.openSession} method and - * sets the {@code Session}'s flush mode to "MANUAL". + *
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 diff --git a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/support/OpenSessionInViewInterceptor.java b/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/support/OpenSessionInViewInterceptor.java index 001bf77627..39233b0acd 100644 --- a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/support/OpenSessionInViewInterceptor.java +++ b/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/support/OpenSessionInViewInterceptor.java @@ -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. - *
The default implementation delegates to the - * {@code SessionFactory.openSession} method and - * sets the {@code Session}'s flush mode to "MANUAL". + *
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 diff --git a/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/support/OpenSessionInterceptor.java b/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/support/OpenSessionInterceptor.java new file mode 100644 index 0000000000..65be305494 --- /dev/null +++ b/spring-orm-hibernate4/src/main/java/org/springframework/orm/hibernate4/support/OpenSessionInterceptor.java @@ -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. + * + *
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. + *
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); + } + } + +} diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/HibernateInterceptor.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/HibernateInterceptor.java index 7d412f693a..8feba6af36 100644 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/HibernateInterceptor.java +++ b/spring-orm/src/main/java/org/springframework/orm/hibernate3/HibernateInterceptor.java @@ -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 { diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/SessionFactoryUtils.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/SessionFactoryUtils.java index 320e155dc2..be43c7bc04 100644 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/SessionFactoryUtils.java +++ b/spring-orm/src/main/java/org/springframework/orm/hibernate3/SessionFactoryUtils.java @@ -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 { *
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 diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/OpenSessionInViewFilter.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/OpenSessionInViewFilter.java index ced44d6f5e..56fa98a83d 100644 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/OpenSessionInViewFilter.java +++ b/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/OpenSessionInViewFilter.java @@ -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. */ diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/OpenSessionInViewInterceptor.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/OpenSessionInViewInterceptor.java index 484d196c8f..b868d797c9 100644 --- a/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/OpenSessionInViewInterceptor.java +++ b/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/OpenSessionInViewInterceptor.java @@ -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; diff --git a/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/OpenSessionInterceptor.java b/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/OpenSessionInterceptor.java new file mode 100644 index 0000000000..3429d71a05 --- /dev/null +++ b/spring-orm/src/main/java/org/springframework/orm/hibernate3/support/OpenSessionInterceptor.java @@ -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. + * + *
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. + * + *
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. + *
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); + } + } + +} diff --git a/spring-orm/src/test/java/org/springframework/orm/hibernate3/support/OpenSessionInViewTests.java b/spring-orm/src/test/java/org/springframework/orm/hibernate3/support/OpenSessionInViewTests.java index 249a161140..7d87483126 100644 --- a/spring-orm/src/test/java/org/springframework/orm/hibernate3/support/OpenSessionInViewTests.java +++ b/spring-orm/src/test/java/org/springframework/orm/hibernate3/support/OpenSessionInViewTests.java @@ -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. @@ -18,11 +18,14 @@ package org.springframework.orm.hibernate3.support; import java.io.IOException; import java.sql.Connection; -import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.atomic.AtomicInteger; - -import javax.servlet.*; +import javax.servlet.AsyncEvent; +import javax.servlet.AsyncListener; +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; import javax.transaction.TransactionManager; import org.hibernate.FlushMode; @@ -32,8 +35,15 @@ import org.hibernate.classic.Session; import org.hibernate.engine.SessionFactoryImplementor; import org.junit.Before; import org.junit.Test; + +import org.springframework.aop.framework.ProxyFactory; import org.springframework.core.task.SimpleAsyncTaskExecutor; -import org.springframework.mock.web.test.*; +import org.springframework.mock.web.test.MockAsyncContext; +import org.springframework.mock.web.test.MockFilterConfig; +import org.springframework.mock.web.test.MockHttpServletRequest; +import org.springframework.mock.web.test.MockHttpServletResponse; +import org.springframework.mock.web.test.MockServletContext; +import org.springframework.mock.web.test.PassThroughFilterChain; import org.springframework.orm.hibernate3.HibernateAccessor; import org.springframework.orm.hibernate3.HibernateTransactionManager; import org.springframework.orm.hibernate3.SessionFactoryUtils; @@ -80,8 +90,33 @@ public class OpenSessionInViewTests { } @Test - public void testOpenSessionInViewInterceptorWithSingleSession() throws Exception { + public void testOpenSessionInterceptor() throws Exception { + final SessionFactory sf = mock(SessionFactory.class); + final Session session = mock(Session.class); + OpenSessionInterceptor interceptor = new OpenSessionInterceptor(); + interceptor.setSessionFactory(sf); + + Runnable tb = new Runnable() { + @Override + public void run() { + assertTrue(TransactionSynchronizationManager.hasResource(sf)); + assertEquals(session, SessionFactoryUtils.getSession(sf, false)); + } + }; + ProxyFactory pf = new ProxyFactory(tb); + pf.addAdvice(interceptor); + Runnable tbProxy = (Runnable) pf.getProxy(); + + given(sf.openSession()).willReturn(session); + given(session.isOpen()).willReturn(true); + tbProxy.run(); + verify(session).setFlushMode(FlushMode.MANUAL); + verify(session).close(); + } + + @Test + public void testOpenSessionInViewInterceptorWithSingleSession() throws Exception { SessionFactory sf = mock(SessionFactory.class); Session session = mock(Session.class); @@ -123,7 +158,6 @@ public class OpenSessionInViewTests { @Test public void testOpenSessionInViewInterceptorAsyncScenario() throws Exception { - // Initial request thread final SessionFactory sf = mock(SessionFactory.class); @@ -171,7 +205,6 @@ public class OpenSessionInViewTests { @Test public void testOpenSessionInViewInterceptorAsyncTimeoutScenario() throws Exception { - // Initial request thread final SessionFactory sf = mock(SessionFactory.class); @@ -234,7 +267,7 @@ public class OpenSessionInViewTests { interceptor.preHandle(this.webRequest); assertTrue(TransactionSynchronizationManager.hasResource(sf)); - // check that further invocations simply participate + // Check that further invocations simply participate interceptor.preHandle(this.webRequest); assertEquals(session, SessionFactoryUtils.getSession(sf, false)); @@ -448,7 +481,6 @@ public class OpenSessionInViewTests { @Test public void testOpenSessionInViewFilterAsyncTimeoutScenario() throws Exception { - final SessionFactory sf = mock(SessionFactory.class); Session session = mock(Session.class); @@ -716,4 +748,5 @@ public class OpenSessionInViewTests { task.run(); } } + }