2012-03-12 37 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

相關問題