2012-03-12 67 views
1

我想在使用Spring的JUnit测试中执行SQL脚本。该脚本正在用于为测试设置数据。但是,脚本运行时,脚本中的INSERT将在每次测试后提交。 Spring文档说不希望用DDL进行回滚,但我脚本中的所有内容都是DML。它包含的所有内容是INSERT语句并获取最后一个插入ID(SET @blah = LAST_INSERT_ID())。使用Spring测试执行SQL脚本测试正在提交更改

我配置错了吗?我正在使用这个对MySQL数据库。我们的配置如下:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = { "/applicationContext.xml" }) 
@TransactionConfiguration(defaultRollback = true) 
public class OrderTestCase extends AbstractTransactionalJUnit4SpringContextTests { 

    @Before 
    public void runSql() { 
     String fileName = StringUtils.replace(getClass().getName(), ".", "/") + ".sql"; 
     Resource resource = applicationContext.getResource(fileName); 
     if (resource.exists()) { 
      executeSqlScript(fileName, false); 
     } else { 
      LOGGER.debug("Resource doesn't exist: {}", resource); 
     } 
    } 

@Test 
public void testLoadOrders() { 
    Collection<Order> orders= dao.findAll(); 
    assertTrue(orders.size() == 3); 
} 
} 

这是我根据一些研究发生的事情。第一次调用executeSqlScript是在一个单独的事务中运行。 Spring的SimpleJdbcTemplate.update方法由executeSqlScript调用。因为这是从连接池获得的JDBC连接的作用域,所以我不保证在随后访问数据库时获得相同的连接,因此无法保证在同一事务中运行。

如果我要通过TransactionManager或(Hibernate Session Factory)完成所有数据库操作,那么它会工作,因为内部机制如何限制事务。在这里,我的选择是:

  1. 图如何运行SimpleJdbcTemplate.update和我在同一个事务测试随后的实际代码。我想我可以做到这一点,但迄今为止我的努力没有结果。

  2. 执行通过SessionFactory设置的所有测试数据。因此,我不是通过JDBC来执行直接的SQL脚本,而是填充模型对象并通过Hibernate DAO持久化它们。

我在正确的轨道上吗?任何人都可以提供更多指导吗?

+0

对我来说看起来没问题。数据源配置是下一个看看 – sw1nn 2012-03-12 21:32:40

回答

0

我可以通过在我的entityManagerFactory的声明中添加下面的'jpaVendorAdapter'来解决这个问题。

<bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory"> 
    <property name="dataSource" ref="dataSource"/> 
     <property name="jpaVendorAdapter"> 
      <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" /> 
     </property> 
</bean> 
1

您可能在数据库连接上启用了自动提交功能。

<bean id="dataSource" 
    class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> 
    <property name="driverClassName" value="${jdbc.driverClassName}"/> 
    <property name="url" value="${jdbc.url}"/> 
    <property name="username" value="${jdbc.username}"/> 
    <property name="password" value="${jdbc.password}"/> 
    <property name="defaultAutoCommit" value="false"/> 
</bean> 

请注意,您可能也会将此参数传递给jdbc url。

+0

看到我上面的编辑。将此设置为auto-commit = false实际上导致testLoadOrders方法在DB中看到零行,即使在执行SQL脚本时插入了3行也是如此。这告诉我,两者都在单独的交易中运行。 – sma 2012-03-13 03:32:27