Java 使用Spring测试执行SQL脚本正在提交更改

Java 使用Spring测试执行SQL脚本正在提交更改,java,spring,junit,spring-transactions,spring-test,Java,Spring,Junit,Spring Transactions,Spring Test,我正在尝试使用Spring在JUnit测试中执行SQL脚本。该脚本用于为测试设置数据。但是,当脚本运行时,脚本中的插入将在每次测试后提交。Spring文档说不要期望使用DDL回滚,但我的脚本中的所有内容都是DML。它只包含INSERT语句和获取最后一个INSERT ID(SET@blah=last_INSERT_ID()) 我配置有问题吗?我正在对MySQL数据库使用它。我们的配置如下: @RunWith(SpringJUnit4ClassRunner.class) @ContextConfig

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

我配置有问题吗?我正在对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);
}
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(位置={“/applicationContext.xml”})
@TransactionConfiguration(defaultRollback=true)
公共类OrderTestCase扩展了AbstractTransactionalJUnit4SpringContextTests{
@以前
public-void-runSql(){
字符串文件名=StringUtils.replace(getClass().getName(),“,”/”+“.sql”;
Resource=applicationContext.getResource(文件名);
if(resource.exists()){
executeSqlScript(文件名,false);
}否则{
debug(“资源不存在:{}”,Resource);
}
}
@试验
公共void testLoadOrders(){
收款单=dao.findAll();
assertTrue(orders.size()=3);
}
}
以下是我根据一些研究认为正在发生的事情。对executeSqlScript的第一个调用在单独的事务中运行。executeSqlScript调用Spring的SimpleJdbcTemplate.update方法。因为这是从连接池获得的JDBC连接的作用域,所以我不能保证在后续访问DB时获得相同的连接,因此不能保证在同一事务中运行

如果我要通过TransactionManager或(Hibernate会话工厂)执行所有的DB操作,那么它将工作,因为内部如何定义事务的范围。我在这里的选择是:

  • 了解如何在同一事务中运行SimpleJdbcTemplate.update和后续实际测试的代码。我想我有可能做到这一点,但迄今为止我的努力毫无结果

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


  • 我走对了吗?有人能提供更多的指导吗?

    您可能已经在db连接上启用了自动提交功能

    
    

    请注意,您可能还在jdbc url中传递此参数。

    您可能在db连接上启用了自动提交

    
    

    请注意,您可能还在jdbc url中传递此参数。

    我可以通过在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>
    

    我可以通过在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>
    
    
    
    我觉得还可以。Datasource config是下一个看起来不错的地方。数据源配置是下一个查看我的上述编辑的地方。将其设置为auto-commit=false实际上导致testLoadOrders方法在DB中看到零行,即使在执行SQL脚本时插入了3行。这告诉我两者都在单独的事务中运行。请参阅我上面的编辑。将其设置为auto-commit=false实际上导致testLoadOrders方法在DB中看到零行,即使在执行SQL脚本时插入了3行。这告诉我两者都在单独的事务中运行。