Package org.springframework.orm.hibernate3.support

Source Code of org.springframework.orm.hibernate3.support.OpenSessionInViewTests$SyncTaskExecutor

/*
* 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 java.io.IOException;
import java.sql.Connection;
import java.util.concurrent.Callable;
import java.util.concurrent.atomic.AtomicInteger;
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;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
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.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;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.context.request.async.AsyncWebRequest;
import org.springframework.web.context.request.async.StandardServletAsyncWebRequest;
import org.springframework.web.context.request.async.WebAsyncManager;
import org.springframework.web.context.request.async.WebAsyncUtils;
import org.springframework.web.context.support.StaticWebApplicationContext;
import org.springframework.web.util.NestedServletException;

import static org.junit.Assert.*;
import static org.mockito.BDDMockito.*;

/**
* @author Juergen Hoeller
* @author Rossen Stoyanchev
* @author Phillip Webb
* @since 05.03.2005
*/
public class OpenSessionInViewTests {

  private MockServletContext sc;

  private MockHttpServletRequest request;

  private MockHttpServletResponse response;

  private ServletWebRequest webRequest;


  @Before
  public void setup() {
    this.sc = new MockServletContext();
    this.request = new MockHttpServletRequest(sc);
    this.request.setAsyncSupported(true);
    this.response = new MockHttpServletResponse();
    this.webRequest = new ServletWebRequest(this.request);
  }

  @Test
  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);

    OpenSessionInViewInterceptor interceptor = new OpenSessionInViewInterceptor();
    interceptor.setSessionFactory(sf);

    given(sf.openSession()).willReturn(session);
    given(session.getSessionFactory()).willReturn(sf);
    given(session.getSessionFactory()).willReturn(sf);
    given(session.isOpen()).willReturn(true);

    interceptor.preHandle(this.webRequest);
    assertTrue(TransactionSynchronizationManager.hasResource(sf));

    // check that further invocations simply participate
    interceptor.preHandle(this.webRequest);
    assertEquals(session, SessionFactoryUtils.getSession(sf, false));

    interceptor.preHandle(this.webRequest);
    interceptor.postHandle(this.webRequest, null);
    interceptor.afterCompletion(this.webRequest, null);

    interceptor.postHandle(this.webRequest, null);
    interceptor.afterCompletion(this.webRequest, null);

    interceptor.preHandle(this.webRequest);
    interceptor.postHandle(this.webRequest, null);
    interceptor.afterCompletion(this.webRequest, null);

    interceptor.postHandle(this.webRequest, null);
    assertTrue(TransactionSynchronizationManager.hasResource(sf));

    interceptor.afterCompletion(this.webRequest, null);
    assertFalse(TransactionSynchronizationManager.hasResource(sf));

    verify(session).setFlushMode(FlushMode.MANUAL);
    verify(session).close();
  }

  @Test
  public void testOpenSessionInViewInterceptorAsyncScenario() throws Exception {
    // Initial request thread

    final SessionFactory sf = mock(SessionFactory.class);
    Session session = mock(Session.class);

    OpenSessionInViewInterceptor interceptor = new OpenSessionInViewInterceptor();
    interceptor.setSessionFactory(sf);

    given(sf.openSession()).willReturn(session);
    given(session.getSessionFactory()).willReturn(sf);

    interceptor.preHandle(this.webRequest);
    assertTrue(TransactionSynchronizationManager.hasResource(sf));

    AsyncWebRequest asyncWebRequest = new StandardServletAsyncWebRequest(this.request, this.response);
    WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(this.request);
    asyncManager.setTaskExecutor(new SyncTaskExecutor());
    asyncManager.setAsyncWebRequest(asyncWebRequest);
    asyncManager.startCallableProcessing(new Callable<String>() {
      @Override
      public String call() throws Exception {
        return "anything";
      }
    });

    interceptor.afterConcurrentHandlingStarted(this.webRequest);
    assertFalse(TransactionSynchronizationManager.hasResource(sf));

    // Async dispatch thread

    interceptor.preHandle(this.webRequest);
    assertTrue("Session not bound to async thread", TransactionSynchronizationManager.hasResource(sf));

    interceptor.postHandle(this.webRequest, null);
    assertTrue(TransactionSynchronizationManager.hasResource(sf));

    verify(session, never()).close();

    interceptor.afterCompletion(this.webRequest, null);
    assertFalse(TransactionSynchronizationManager.hasResource(sf));

    verify(session).setFlushMode(FlushMode.MANUAL);
    verify(session).close();
  }

  @Test
  public void testOpenSessionInViewInterceptorAsyncTimeoutScenario() throws Exception {
    // Initial request thread

    final SessionFactory sf = mock(SessionFactory.class);
    Session session = mock(Session.class);

    OpenSessionInViewInterceptor interceptor = new OpenSessionInViewInterceptor();
    interceptor.setSessionFactory(sf);

    given(sf.openSession()).willReturn(session);
    given(session.getSessionFactory()).willReturn(sf);

    interceptor.preHandle(this.webRequest);
    assertTrue(TransactionSynchronizationManager.hasResource(sf));

    AsyncWebRequest asyncWebRequest = new StandardServletAsyncWebRequest(this.request, this.response);
    WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(this.request);
    asyncManager.setTaskExecutor(new SyncTaskExecutor());
    asyncManager.setAsyncWebRequest(asyncWebRequest);
    asyncManager.startCallableProcessing(new Callable<String>() {
      @Override
      public String call() throws Exception {
        return "anything";
      }
    });

    interceptor.afterConcurrentHandlingStarted(this.webRequest);
    assertFalse(TransactionSynchronizationManager.hasResource(sf));
    verify(session, never()).close();

    // Async request timeout

    MockAsyncContext asyncContext = (MockAsyncContext) this.request.getAsyncContext();
    for (AsyncListener listener : asyncContext.getListeners()) {
      listener.onTimeout(new AsyncEvent(asyncContext));
    }
    for (AsyncListener listener : asyncContext.getListeners()) {
      listener.onComplete(new AsyncEvent(asyncContext));
    }

    verify(session).close();
  }

  @Test
  public void testOpenSessionInViewInterceptorWithSingleSessionAndJtaTm() throws Exception {
    final SessionFactoryImplementor sf = mock(SessionFactoryImplementor.class);
    Session session = mock(Session.class);

    TransactionManager tm = mock(TransactionManager.class);
    given(tm.getTransaction()).willReturn(null);
    given(tm.getTransaction()).willReturn(null);

    OpenSessionInViewInterceptor interceptor = new OpenSessionInViewInterceptor();
    interceptor.setSessionFactory(sf);

    given(sf.openSession()).willReturn(session);
    given(sf.getTransactionManager()).willReturn(tm);
    given(sf.getTransactionManager()).willReturn(tm);
    given(session.isOpen()).willReturn(true);

    interceptor.preHandle(this.webRequest);
    assertTrue(TransactionSynchronizationManager.hasResource(sf));

    // Check that further invocations simply participate
    interceptor.preHandle(this.webRequest);

    assertEquals(session, SessionFactoryUtils.getSession(sf, false));

    interceptor.preHandle(this.webRequest);
    interceptor.postHandle(this.webRequest, null);
    interceptor.afterCompletion(this.webRequest, null);

    interceptor.postHandle(this.webRequest, null);
    interceptor.afterCompletion(this.webRequest, null);

    interceptor.preHandle(this.webRequest);
    interceptor.postHandle(this.webRequest, null);
    interceptor.afterCompletion(this.webRequest, null);

    interceptor.postHandle(this.webRequest, null);
    assertTrue(TransactionSynchronizationManager.hasResource(sf));

    interceptor.afterCompletion(this.webRequest, null);
    assertFalse(TransactionSynchronizationManager.hasResource(sf));

    verify(session).setFlushMode(FlushMode.MANUAL);
    verify(session).close();
  }

  @Test
  public void testOpenSessionInViewInterceptorWithSingleSessionAndFlush() throws Exception {
    SessionFactory sf = mock(SessionFactory.class);
    Session session = mock(Session.class);

    OpenSessionInViewInterceptor interceptor = new OpenSessionInViewInterceptor();
    interceptor.setSessionFactory(sf);
    interceptor.setFlushMode(HibernateAccessor.FLUSH_AUTO);

    given(sf.openSession()).willReturn(session);
    given(session.getSessionFactory()).willReturn(sf);
    interceptor.preHandle(this.webRequest);
    assertTrue(TransactionSynchronizationManager.hasResource(sf));

    interceptor.postHandle(this.webRequest, null);
    assertTrue(TransactionSynchronizationManager.hasResource(sf));

    interceptor.afterCompletion(this.webRequest, null);
    assertFalse(TransactionSynchronizationManager.hasResource(sf));
    verify(session).flush();
    verify(session).close();
  }

  @Test
  public void testOpenSessionInViewInterceptorAndDeferredClose() throws Exception {
    SessionFactory sf = mock(SessionFactory.class);
    Session session = mock(Session.class);

    OpenSessionInViewInterceptor interceptor = new OpenSessionInViewInterceptor();
    interceptor.setSessionFactory(sf);
    interceptor.setSingleSession(false);

    given(sf.openSession()).willReturn(session);
    given(session.getSessionFactory()).willReturn(sf);

    interceptor.preHandle(this.webRequest);
    org.hibernate.Session sess = SessionFactoryUtils.getSession(sf, true);
    SessionFactoryUtils.releaseSession(sess, sf);

    // check that further invocations simply participate
    interceptor.preHandle(this.webRequest);

    interceptor.preHandle(this.webRequest);
    interceptor.postHandle(this.webRequest, null);
    interceptor.afterCompletion(this.webRequest, null);

    interceptor.postHandle(this.webRequest, null);
    interceptor.afterCompletion(this.webRequest, null);

    interceptor.preHandle(this.webRequest);
    interceptor.postHandle(this.webRequest, null);
    interceptor.afterCompletion(this.webRequest, null);

    interceptor.postHandle(this.webRequest, null);
    interceptor.afterCompletion(this.webRequest, null);

    verify(session).setFlushMode(FlushMode.MANUAL);
    verify(session).close();
  }

  @Test
  public void testOpenSessionInViewFilterWithSingleSession() throws Exception {
    final SessionFactory sf = mock(SessionFactory.class);
    Session session = mock(Session.class);

    given(sf.openSession()).willReturn(session);
    given(session.getSessionFactory()).willReturn(sf);
    given(session.close()).willReturn(null);

    final SessionFactory sf2 = mock(SessionFactory.class);
    Session session2 = mock(Session.class);

    given(sf2.openSession()).willReturn(session2);
    given(session2.getSessionFactory()).willReturn(sf2);
    given(session2.close()).willReturn(null);

    StaticWebApplicationContext wac = new StaticWebApplicationContext();
    wac.setServletContext(sc);
    wac.getDefaultListableBeanFactory().registerSingleton("sessionFactory", sf);
    wac.getDefaultListableBeanFactory().registerSingleton("mySessionFactory", sf2);
    wac.refresh();
    sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);

    MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter");
    MockFilterConfig filterConfig2 = new MockFilterConfig(wac.getServletContext(), "filter2");
    filterConfig2.addInitParameter("sessionFactoryBeanName", "mySessionFactory");
    filterConfig2.addInitParameter("flushMode", "AUTO");

    final OpenSessionInViewFilter filter = new OpenSessionInViewFilter();
    filter.init(filterConfig);
    final OpenSessionInViewFilter filter2 = new OpenSessionInViewFilter();
    filter2.init(filterConfig2);

    final FilterChain filterChain = new FilterChain() {
      @Override
      public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
        assertTrue(TransactionSynchronizationManager.hasResource(sf));
        servletRequest.setAttribute("invoked", Boolean.TRUE);
      }
    };

    final FilterChain filterChain2 = new FilterChain() {
      @Override
      public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse)
        throws IOException, ServletException {
        assertTrue(TransactionSynchronizationManager.hasResource(sf2));
        filter.doFilter(servletRequest, servletResponse, filterChain);
      }
    };

    FilterChain filterChain3 = new PassThroughFilterChain(filter2, filterChain2);

    assertFalse(TransactionSynchronizationManager.hasResource(sf));
    assertFalse(TransactionSynchronizationManager.hasResource(sf2));
    filter2.doFilter(this.request, this.response, filterChain3);
    assertFalse(TransactionSynchronizationManager.hasResource(sf));
    assertFalse(TransactionSynchronizationManager.hasResource(sf2));
    assertNotNull(this.request.getAttribute("invoked"));

    verify(session).setFlushMode(FlushMode.MANUAL);
    verify(session2).setFlushMode(FlushMode.AUTO);
    wac.close();
  }

  @Test
  public void testOpenSessionInViewFilterAsyncScenario() throws Exception {
    final SessionFactory sf = mock(SessionFactory.class);
    Session session = mock(Session.class);

    // Initial request during which concurrent handling starts..

    given(sf.openSession()).willReturn(session);
    given(session.getSessionFactory()).willReturn(sf);

    StaticWebApplicationContext wac = new StaticWebApplicationContext();
    wac.setServletContext(sc);
    wac.getDefaultListableBeanFactory().registerSingleton("sessionFactory", sf);
    wac.refresh();
    sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);

    MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter");

    final AtomicInteger count = new AtomicInteger(0);

    final OpenSessionInViewFilter filter = new OpenSessionInViewFilter();
    filter.init(filterConfig);

    final FilterChain filterChain = new FilterChain() {
      @Override
      public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
        assertTrue(TransactionSynchronizationManager.hasResource(sf));
        count.incrementAndGet();
      }
    };

    AsyncWebRequest asyncWebRequest = new StandardServletAsyncWebRequest(this.request, this.response);
    WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(this.request);
    asyncManager.setTaskExecutor(new SyncTaskExecutor());
    asyncManager.setAsyncWebRequest(asyncWebRequest);
    asyncManager.startCallableProcessing(new Callable<String>() {
      @Override
      public String call() throws Exception {
        return "anything";
      }
    });

    assertFalse(TransactionSynchronizationManager.hasResource(sf));
    filter.doFilter(this.request, this.response, filterChain);
    assertFalse(TransactionSynchronizationManager.hasResource(sf));
    assertEquals(1, count.get());
    verify(session, never()).close();

    // Async dispatch after concurrent handling produces result ...

    this.request.setAsyncStarted(false);
    assertFalse(TransactionSynchronizationManager.hasResource(sf));
    filter.doFilter(this.request, this.response, filterChain);
    assertFalse(TransactionSynchronizationManager.hasResource(sf));
    assertEquals(2, count.get());

    verify(session).setFlushMode(FlushMode.MANUAL);
    verify(session).close();

    wac.close();
  }

  @Test
  public void testOpenSessionInViewFilterAsyncTimeoutScenario() throws Exception {
    final SessionFactory sf = mock(SessionFactory.class);
    Session session = mock(Session.class);

    // Initial request during which concurrent handling starts..

    given(sf.openSession()).willReturn(session);
    given(session.getSessionFactory()).willReturn(sf);

    StaticWebApplicationContext wac = new StaticWebApplicationContext();
    wac.setServletContext(sc);
    wac.getDefaultListableBeanFactory().registerSingleton("sessionFactory", sf);
    wac.refresh();
    sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);

    MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter");
    final OpenSessionInViewFilter filter = new OpenSessionInViewFilter();
    filter.init(filterConfig);

    final AtomicInteger count = new AtomicInteger(0);
    final AsyncWebRequest asyncWebRequest = new StandardServletAsyncWebRequest(this.request, this.response);
    final MockHttpServletRequest request = this.request;

    final FilterChain filterChain = new FilterChain() {
      @Override
      public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse)
          throws NestedServletException {

        assertTrue(TransactionSynchronizationManager.hasResource(sf));
        count.incrementAndGet();

        WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
        asyncManager.setTaskExecutor(new SyncTaskExecutor());
        asyncManager.setAsyncWebRequest(asyncWebRequest);
        try {
          asyncManager.startCallableProcessing(new Callable<String>() {
            @Override
            public String call() throws Exception {
              return "anything";
            }
          });
        }
        catch (Exception e) {
          throw new NestedServletException("", e);
        }
      }
    };

    assertFalse(TransactionSynchronizationManager.hasResource(sf));
    filter.doFilter(this.request, this.response, filterChain);
    assertFalse(TransactionSynchronizationManager.hasResource(sf));
    assertEquals(1, count.get());
    verify(session, never()).close();

    // Async request timeout ...

    MockAsyncContext asyncContext = (MockAsyncContext) this.request.getAsyncContext();
    for (AsyncListener listener : asyncContext.getListeners()) {
      listener.onTimeout(new AsyncEvent(asyncContext));
    }
    for (AsyncListener listener : asyncContext.getListeners()) {
      listener.onComplete(new AsyncEvent(asyncContext));
    }

    verify(session).close();

    wac.close();
  }

  @Test
  public void testOpenSessionInViewFilterWithSingleSessionAndPreBoundSession() throws Exception {
    final SessionFactory sf = mock(SessionFactory.class);
    Session session = mock(Session.class);

    given(sf.openSession()).willReturn(session);
    given(session.getSessionFactory()).willReturn(sf);

    StaticWebApplicationContext wac = new StaticWebApplicationContext();
    wac.setServletContext(sc);
    wac.getDefaultListableBeanFactory().registerSingleton("sessionFactory", sf);
    wac.refresh();
    sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);

    MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter");
    MockFilterConfig filterConfig2 = new MockFilterConfig(wac.getServletContext(), "filter2");
    filterConfig2.addInitParameter("sessionFactoryBeanName", "mySessionFactory");

    OpenSessionInViewInterceptor interceptor = new OpenSessionInViewInterceptor();
    interceptor.setSessionFactory(sf);

    interceptor.preHandle(this.webRequest);

    final OpenSessionInViewFilter filter = new OpenSessionInViewFilter();
    filter.init(filterConfig);

    final FilterChain filterChain = new FilterChain() {
      @Override
      public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
        assertTrue(TransactionSynchronizationManager.hasResource(sf));
        servletRequest.setAttribute("invoked", Boolean.TRUE);
      }
    };

    assertTrue(TransactionSynchronizationManager.hasResource(sf));
    filter.doFilter(this.request, this.response, filterChain);
    assertTrue(TransactionSynchronizationManager.hasResource(sf));
    assertNotNull(this.request.getAttribute("invoked"));

    interceptor.postHandle(this.webRequest, null);
    interceptor.afterCompletion(this.webRequest, null);

    verify(session).setFlushMode(FlushMode.MANUAL);
    verify(session).close();

    wac.close();
  }

  @Test
  public void testOpenSessionInViewFilterWithDeferredClose() throws Exception {
    final SessionFactory sf = mock(SessionFactory.class);
    final Session session = mock(Session.class);

    given(sf.openSession()).willReturn(session);
    given(session.getSessionFactory()).willReturn(sf);
    given(session.getFlushMode()).willReturn(FlushMode.MANUAL);

    final SessionFactory sf2 = mock(SessionFactory.class);
    final Session session2 = mock(Session.class);

    Transaction tx = mock(Transaction.class);
    Connection con = mock(Connection.class);

    given(sf2.openSession()).willReturn(session2);
    given(session2.connection()).willReturn(con);
    given(session2.beginTransaction()).willReturn(tx);
    given(session2.isConnected()).willReturn(true);
    given(session2.connection()).willReturn(con);

    StaticWebApplicationContext wac = new StaticWebApplicationContext();
    wac.setServletContext(sc);
    wac.getDefaultListableBeanFactory().registerSingleton("sessionFactory", sf);
    wac.getDefaultListableBeanFactory().registerSingleton("mySessionFactory", sf2);
    wac.refresh();
    sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);

    MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter");
    MockFilterConfig filterConfig2 = new MockFilterConfig(wac.getServletContext(), "filter2");
    filterConfig.addInitParameter("singleSession", "false");
    filterConfig2.addInitParameter("singleSession", "false");
    filterConfig2.addInitParameter("sessionFactoryBeanName", "mySessionFactory");

    final OpenSessionInViewFilter filter = new OpenSessionInViewFilter();
    filter.init(filterConfig);
    final OpenSessionInViewFilter filter2 = new OpenSessionInViewFilter();
    filter2.init(filterConfig2);

    final FilterChain filterChain = new FilterChain() {
      @Override
      public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
        HibernateTransactionManager tm = new HibernateTransactionManager(sf);
        TransactionStatus ts = tm.getTransaction(
            new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_SUPPORTS));
        org.hibernate.Session sess = SessionFactoryUtils.getSession(sf, true);
        SessionFactoryUtils.releaseSession(sess, sf);
        tm.commit(ts);
        servletRequest.setAttribute("invoked", Boolean.TRUE);
      }
    };

    final FilterChain filterChain2 = new FilterChain() {
      @Override
      public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse)
        throws IOException, ServletException {
        HibernateTransactionManager tm = new HibernateTransactionManager(sf2);
        TransactionStatus ts = tm.getTransaction(new DefaultTransactionDefinition());
        tm.commit(ts);
        filter.doFilter(servletRequest, servletResponse, filterChain);
      }
    };

    FilterChain filterChain3 = new PassThroughFilterChain(filter2, filterChain2);

    filter2.doFilter(this.request, this.response, filterChain3);
    assertNotNull(this.request.getAttribute("invoked"));

    verify(session).setFlushMode(FlushMode.MANUAL);
    verify(tx).commit();
    verify(session2).setFlushMode(FlushMode.MANUAL);
    verify(session).close();
    verify(session2).close();

    wac.close();
  }

  @Test
  public void testOpenSessionInViewFilterWithDeferredCloseAndAlreadyActiveDeferredClose() throws Exception {
    final SessionFactory sf = mock(SessionFactory.class);
    final Session session = mock(Session.class);

    given(sf.openSession()).willReturn(session);
    given(session.getSessionFactory()).willReturn(sf);
    given(session.getFlushMode()).willReturn(FlushMode.MANUAL);

    StaticWebApplicationContext wac = new StaticWebApplicationContext();
    wac.setServletContext(sc);
    wac.getDefaultListableBeanFactory().registerSingleton("sessionFactory", sf);
    wac.refresh();
    sc.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, wac);

    MockFilterConfig filterConfig = new MockFilterConfig(wac.getServletContext(), "filter");
    MockFilterConfig filterConfig2 = new MockFilterConfig(wac.getServletContext(), "filter2");
    filterConfig.addInitParameter("singleSession", "false");
    filterConfig2.addInitParameter("singleSession", "false");
    filterConfig2.addInitParameter("sessionFactoryBeanName", "mySessionFactory");

    OpenSessionInViewInterceptor interceptor = new OpenSessionInViewInterceptor();
    interceptor.setSessionFactory(sf);
    interceptor.setSingleSession(false);

    interceptor.preHandle(webRequest);

    final OpenSessionInViewFilter filter = new OpenSessionInViewFilter();
    filter.init(filterConfig);
    final OpenSessionInViewFilter filter2 = new OpenSessionInViewFilter();
    filter2.init(filterConfig2);

    final FilterChain filterChain = new FilterChain() {
      @Override
      public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse) {
        HibernateTransactionManager tm = new HibernateTransactionManager(sf);
        TransactionStatus ts = tm.getTransaction(
            new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_SUPPORTS));
        org.hibernate.Session sess = SessionFactoryUtils.getSession(sf, true);
        SessionFactoryUtils.releaseSession(sess, sf);
        tm.commit(ts);
        servletRequest.setAttribute("invoked", Boolean.TRUE);
      }
    };

    FilterChain filterChain2 = new FilterChain() {
      @Override
      public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse)
        throws IOException, ServletException {
        filter.doFilter(servletRequest, servletResponse, filterChain);
      }
    };

    filter.doFilter(this.request, this.response, filterChain2);
    assertNotNull(this.request.getAttribute("invoked"));

    interceptor.postHandle(webRequest, null);
    interceptor.afterCompletion(webRequest, null);

    verify(session).setFlushMode(FlushMode.MANUAL);
    verify(session).close();

    wac.close();
  }


  @SuppressWarnings("serial")
  private static class SyncTaskExecutor extends SimpleAsyncTaskExecutor {

    @Override
    public void execute(Runnable task, long startTimeout) {
      task.run();
    }
  }

}
TOP

Related Classes of org.springframework.orm.hibernate3.support.OpenSessionInViewTests$SyncTaskExecutor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.