Package org.springframework.webflow.persistence

Source Code of org.springframework.webflow.persistence.HibernateFlowExecutionListenerTests

/*
* Copyright 2004-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.webflow.persistence;

import javax.sql.DataSource;

import junit.framework.TestCase;

import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.jdbc.datasource.init.DataSourceInitializer;
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
import org.springframework.orm.hibernate4.HibernateCallback;
import org.springframework.orm.hibernate4.HibernateTemplate;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.webflow.engine.EndState;
import org.springframework.webflow.execution.FlowExecutionException;
import org.springframework.webflow.test.MockFlowSession;
import org.springframework.webflow.test.MockRequestContext;

/**
* Tests for {@link HibernateFlowExecutionListener}
*
* @author Ben Hale
*/
public class HibernateFlowExecutionListenerTests extends TestCase {

  private SessionFactory sessionFactory;

  private JdbcTemplate jdbcTemplate;

  private HibernateTemplate hibernateTemplate;

  private HibernateFlowExecutionListener hibernateListener;

  protected void setUp() throws Exception {
    DataSource dataSource = getDataSource();
    populateDataBase(dataSource);
    jdbcTemplate = new JdbcTemplate(dataSource);
    sessionFactory = getSessionFactory(dataSource);
    hibernateTemplate = new HibernateTemplate(sessionFactory);
    hibernateTemplate.setCheckWriteOperations(false);
    HibernateTransactionManager tm = new HibernateTransactionManager(sessionFactory);
    hibernateListener = new HibernateFlowExecutionListener(sessionFactory, tm);
  }

  public void testSameSession() {
    MockRequestContext context = new MockRequestContext();
    MockFlowSession flowSession = new MockFlowSession();
    flowSession.getDefinition().getAttributes().put("persistenceContext", "true");
    hibernateListener.sessionStarting(context, flowSession, null);
    context.setActiveSession(flowSession);
    assertSessionBound();

    // Session created and bound to conversation
    final Session hibSession = (Session) flowSession.getScope().get("persistenceContext");
    assertNotNull("Should have been populated", hibSession);
    hibernateListener.paused(context);
    assertSessionNotBound();

    // Session bound to thread local variable
    hibernateListener.resuming(context);
    assertSessionBound();

    hibernateTemplate.executeWithNativeSession(new HibernateCallback<Object>() {
      public Object doInHibernate(Session session) {
        assertSame("Should have been original instance", hibSession, session);
        return null;
      }
    });
    hibernateListener.paused(context);
    assertSessionNotBound();
  }

  public void testFlowNotAPersistenceContext() {
    MockRequestContext context = new MockRequestContext();
    MockFlowSession flowSession = new MockFlowSession();
    hibernateListener.sessionStarting(context, flowSession, null);
    assertSessionNotBound();
  }

  public void testFlowCommitsInSingleRequest() {
    assertEquals("Table should only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN"));
    MockRequestContext context = new MockRequestContext();
    MockFlowSession flowSession = new MockFlowSession();
    flowSession.getDefinition().getAttributes().put("persistenceContext", "true");
    hibernateListener.sessionStarting(context, flowSession, null);
    context.setActiveSession(flowSession);
    assertSessionBound();

    TestBean bean = new TestBean("Keith Donald");
    hibernateTemplate.save(bean);
    assertEquals("Table should still only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN"));

    EndState endState = new EndState(flowSession.getDefinitionInternal(), "success");
    endState.getAttributes().put("commit", true);
    flowSession.setState(endState);

    hibernateListener.sessionEnding(context, flowSession, "success", null);
    hibernateListener.sessionEnded(context, flowSession, "success", null);
    assertEquals("Table should only have two rows", 2, jdbcTemplate.queryForInt("select count(*) from T_BEAN"));
    assertSessionNotBound();
  }

  public void testFlowCommitsAfterMultipleRequests() {
    assertEquals("Table should only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN"));
    MockRequestContext context = new MockRequestContext();
    MockFlowSession flowSession = new MockFlowSession();
    flowSession.getDefinition().getAttributes().put("persistenceContext", "true");
    hibernateListener.sessionStarting(context, flowSession, null);
    context.setActiveSession(flowSession);
    assertSessionBound();

    TestBean bean1 = new TestBean("Keith Donald");
    hibernateTemplate.save(bean1);
    assertEquals("Table should still only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN"));
    hibernateListener.paused(context);
    assertSessionNotBound();

    hibernateListener.resuming(context);
    TestBean bean2 = new TestBean("Keith Donald");
    hibernateTemplate.save(bean2);
    assertEquals("Table should still only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN"));
    assertSessionBound();

    EndState endState = new EndState(flowSession.getDefinitionInternal(), "success");
    endState.getAttributes().put("commit", true);
    flowSession.setState(endState);

    hibernateListener.sessionEnding(context, flowSession, "success", null);
    hibernateListener.sessionEnded(context, flowSession, "success", null);
    assertEquals("Table should only have three rows", 3, jdbcTemplate.queryForInt("select count(*) from T_BEAN"));

    assertSessionNotBound();
  }

  public void testCancelEndState() {
    assertEquals("Table should only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN"));
    MockRequestContext context = new MockRequestContext();
    MockFlowSession flowSession = new MockFlowSession();
    flowSession.getDefinition().getAttributes().put("persistenceContext", "true");
    hibernateListener.sessionStarting(context, flowSession, null);
    context.setActiveSession(flowSession);
    assertSessionBound();

    TestBean bean = new TestBean("Keith Donald");
    hibernateTemplate.save(bean);
    assertEquals("Table should still only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN"));

    EndState endState = new EndState(flowSession.getDefinitionInternal(), "cancel");
    endState.getAttributes().put("commit", false);
    flowSession.setState(endState);
    hibernateListener.sessionEnding(context, flowSession, "success", null);
    hibernateListener.sessionEnded(context, flowSession, "cancel", null);
    assertEquals("Table should only have two rows", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN"));
    assertSessionNotBound();
  }

  public void testNoCommitAttributeSetOnEndState() {
    assertEquals("Table should only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN"));
    MockRequestContext context = new MockRequestContext();
    MockFlowSession flowSession = new MockFlowSession();
    flowSession.getDefinition().getAttributes().put("persistenceContext", "true");
    hibernateListener.sessionStarting(context, flowSession, null);
    context.setActiveSession(flowSession);
    assertSessionBound();

    EndState endState = new EndState(flowSession.getDefinitionInternal(), "cancel");
    flowSession.setState(endState);

    hibernateListener.sessionEnding(context, flowSession, "success", null);
    hibernateListener.sessionEnded(context, flowSession, "cancel", null);
    assertEquals("Table should only have three rows", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN"));

    assertSessionNotBound();
  }

  public void testExceptionThrown() {
    assertEquals("Table should only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN"));
    MockRequestContext context = new MockRequestContext();
    MockFlowSession flowSession = new MockFlowSession();
    flowSession.getDefinition().getAttributes().put("persistenceContext", "true");
    hibernateListener.sessionStarting(context, flowSession, null);
    context.setActiveSession(flowSession);
    assertSessionBound();

    TestBean bean1 = new TestBean("Keith Donald");
    hibernateTemplate.save(bean1);
    assertEquals("Table should still only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN"));
    hibernateListener.exceptionThrown(context, new FlowExecutionException("bla", "bla", "bla"));
    assertEquals("Table should still only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN"));
    assertSessionNotBound();

  }

  public void testExceptionThrownWithNothingBound() {
    assertEquals("Table should only have one row", 1, jdbcTemplate.queryForInt("select count(*) from T_BEAN"));
    MockRequestContext context = new MockRequestContext();
    MockFlowSession flowSession = new MockFlowSession();
    flowSession.getDefinition().getAttributes().put("persistenceContext", "true");
    assertSessionNotBound();
    hibernateListener.exceptionThrown(context, new FlowExecutionException("foo", "bar", "test"));
    assertSessionNotBound();
  }

  public void testLazyInitializedCollection() {
    MockRequestContext context = new MockRequestContext();
    MockFlowSession flowSession = new MockFlowSession();
    flowSession.getDefinition().getAttributes().put("persistenceContext", "true");
    hibernateListener.sessionStarting(context, flowSession, null);
    context.setActiveSession(flowSession);
    assertSessionBound();

    TestBean bean = hibernateTemplate.get(TestBean.class, Long.valueOf(0));
    assertFalse("addresses should not be initialized", Hibernate.isInitialized(bean.getAddresses()));
    hibernateListener.paused(context);
    assertFalse("addresses should not be initialized", Hibernate.isInitialized(bean.getAddresses()));
    Hibernate.initialize(bean.getAddresses());
    assertTrue("addresses should be initialized", Hibernate.isInitialized(bean.getAddresses()));
  }

  private DataSource getDataSource() {
    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setDriverClassName("org.hsqldb.jdbcDriver");
    dataSource.setUrl("jdbc:hsqldb:mem:hspcl");
    dataSource.setUsername("sa");
    dataSource.setPassword("");
    return dataSource;
  }

  private void populateDataBase(DataSource dataSource) throws Exception {
    ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator();
    databasePopulator.addScript(new ClassPathResource("test-data.sql", this.getClass()));
    DataSourceInitializer initializer = new DataSourceInitializer();
    initializer.setDataSource(dataSource);
    initializer.setDatabasePopulator(databasePopulator);
    initializer.afterPropertiesSet();
  }

  private SessionFactory getSessionFactory(DataSource dataSource) throws Exception {
    LocalSessionFactoryBean factory = new LocalSessionFactoryBean();
    factory.setDataSource(dataSource);
    factory.setMappingLocations(new Resource[] {
        new ClassPathResource("org/springframework/webflow/persistence/TestBean.hbm.xml"),
        new ClassPathResource("org/springframework/webflow/persistence/TestAddress.hbm.xml") });
    factory.afterPropertiesSet();
    return factory.getObject();
  }

  private void assertSessionNotBound() {
    assertNull(TransactionSynchronizationManager.getResource(sessionFactory));
  }

  private void assertSessionBound() {
    assertNotNull(TransactionSynchronizationManager.getResource(sessionFactory));
  }

}
TOP

Related Classes of org.springframework.webflow.persistence.HibernateFlowExecutionListenerTests

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.