1

Spring を使用して JUnit テストで SQL スクリプトを実行しようとしています。スクリプトは、テスト用のデータを設定するために使用されています。ただし、スクリプトが実行されると、スクリプト内の INSERT は各テストの後にコミットされます。Spring のドキュメントには、DDL によるロールバックは期待できないと書かれていますが、スクリプト内のすべてが DML です。含まれているのは、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);
}
}

これが、いくつかの調査に基づいて起こっていると私が思うことです。executeSqlScript への最初の呼び出しは、別のトランザクションで実行されています。Spring の SimpleJdbcTemplate.update メソッドは、executeSqlScript によって呼び出されます。これは、接続プールから取得される JDBC 接続にスコープが設定されているため、DB への後続のアクセスで同じ接続を取得することが保証されていないため、同じトランザクションで実行されることを保証できません。

TransactionManager または (Hibernate Session Factory) を介してすべての DB 操作を行う場合、内部がトランザクションをスコープする方法のために機能します。ここでの私のオプションは次のとおりです。

  1. SimpleJdbcTemplate.update を実行する方法と、同じトランザクションでテストしている後続の実際のコードを理解してください。これはできると思いますが、これまでの努力は実を結びませんでした。

  2. SessionFactory を介してすべてのテスト データの設定を行います。したがって、JDBC を介して単純な SQL スクリプトを実行する代わりに、モデル オブジェクトにデータを入力し、Hibernate DAO を介して永続化します。

私はここで正しい軌道に乗っていますか?誰でもこれ以上のガイダンスを提供できますか?

4

2 に答える 2

1

おそらく、db 接続で自動コミットが有効になっています。

<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 で渡すこともあることに注意してください。

于 2012-03-12T21:34:51.653 に答える
0

次の「jpaVendorAdapter」をentityManagerFactoryの宣言に追加することで、これを解決できました。

<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>
于 2012-03-14T01:51:03.963 に答える