3

ロールバックするJUnitテストの設定に問題があります。質問を書くことを決定する前に、SOに関するこれらの投稿のいくつかを読んだことがあります。私の問題に対する答えはないようです。

最初のテストケースからデータがDBに挿入されて永続化されるため、2番目のテストケースは失敗します。

JUnitテストは次のとおりです。

package com.company.group.spring.dao;

import static org.junit.Assert.assertNotNull;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.test.context.transaction.TransactionConfiguration;
import org.springframework.test.context.transaction.TransactionalTestExecutionListener;
import org.springframework.transaction.annotation.Transactional;

import com.company.group.spring.model.BusObj;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:NAME_OF_CONFIG_FILE.xml"})
@Transactional
@TransactionConfiguration(transactionManager = "txManager", defaultRollback = true)
@TestExecutionListeners({TransactionalTestExecutionListener.class,
    DependencyInjectionTestExecutionListener.class}) 
public class PerPartsWCDAOTest {

    @Autowired
    @Qualifier("myBusObjDAO")
    private BusObjDAO busObj_dao;

    @Transactional
    @Test
    public void testInsertRollback() {
        try {
        BusObj busObj = new BusObj("some data...");

        assertNotNull(busObj_dao);
        assertNotNull(busObj);

        busObj_dao.insert(perPartWC);
        }
        catch (NullPointerException e) {
            e.printStackTrace();
        }
    }

    @Transactional
    @Rollback(false)
    @Test
    public void testInsert() {
        BusObj busObj2 = new BusObj("some data...");

        busObj_dao.insert(perPartWC2);
    }

}

これがDAOImplクラス(私がテストしようとしているクラス)です:

package com.company.group.spring.dao;

import javax.sql.DataSource;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import com.company.group.spring.model.BusObj;

@Repository("myBusObjDAO")
public class myBusObjDAOImpl implements myBusObjDAO {

private NamedParameterJdbcTemplate jdbcTemplate;

@Autowired
public void setDataSource(DataSource dataSource) {
    this.jdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
}

@Override
public void insert(BusObj someObj) {
    String sql = "insert into TABLE (args...) " +
            "VALUES (:named_params....)";

    SqlParameterSource paramSource = new BeanPropertySqlParameterSource(someObj);

    jdbcTemplate.update(sql, paramSource);
}

}

関連する構成の一部:

  <tx:annotation-driven transaction-manager="txManager" proxy-target-class="true" />


  <bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource">
      <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
      <property name="url" value="jdbc:oracle:thin:@SERVER:PORT:DB"/>
      <property name="username" value="USER"/>
      <property name="password" value="XXXXXX"/>

  </bean>

編集:+ debug print

2012-12-18 08:50:42,177 [main] DEBUG [org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction()] Creating new transaction with name [com.company.group.spring.service.MyClassService.create]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT

2012-12-18 08:50:42,342 [main] DEBUG [org.springframework.orm.hibernate4.HibernateTransactionManager.doBegin()] Opened new Session [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=[] updates=[] deletions=[] collectionCreations=[] collectionRemovals=[] collectionUpdates=[] unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])] for Hibernate transaction

2012-12-18 08:50:42,344 [main] DEBUG [org.springframework.orm.hibernate4.HibernateTransactionManager.doBegin()] Preparing JDBC Connection of Hibernate Session [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=[] updates=[] deletions=[] collectionCreations=[] collectionRemovals=[] collectionUpdates=[] unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])]

2012-12-18 08:50:42,361 [main] DEBUG [org.springframework.orm.hibernate4.HibernateTransactionManager.doBegin()] Exposing Hibernate transaction as JDBC transaction [org.hibernate.engine.jdbc.internal.proxy.ConnectionProxyHandler@128647a[valid=true]]

2012-12-18 08:50:42,390 [main] DEBUG [org.springframework.jdbc.core.JdbcTemplate.update()] Executing prepared SQL update

2012-12-18 08:50:42,391 [main] DEBUG [org.springframework.jdbc.core.JdbcTemplate.execute()] Executing prepared SQL statement [insert into TABLE (args...) VALUES (?, ?, SYSDATE,?, ?, SYSDATE, ?,?, ?)]

2012-12-18 08:50:42,391 [main] DEBUG [org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection()] Fetching JDBC Connection from DataSource

2012-12-18 08:50:42,657 [main] DEBUG [org.springframework.jdbc.datasource.DataSourceUtils.doGetConnection()] Registering transaction synchronization for JDBC Connection

2012-12-18 08:50:42,671 [main] DEBUG [org.springframework.jdbc.core.JdbcTemplate$2.doInPreparedStatement()] SQL update affected 1 rows

2012-12-18 08:50:42,678 [main] DEBUG [org.springframework.jdbc.datasource.DataSourceUtils.doReleaseConnection()] Returning JDBC Connection to DataSource

2012-12-18 08:50:42,688 [main] DEBUG [org.springframework.transaction.support.AbstractPlatformTransactionManager.processRollback()] Initiating transaction rollback

2012-12-18 08:50:42,688 [main] DEBUG [org.springframework.orm.hibernate4.HibernateTransactionManager.doRollback()] Rolling back Hibernate transaction on Session [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=[] updates=[] deletions=[] collectionCreations=[] collectionRemovals=[] collectionUpdates=[] unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])]

2012-12-18 08:50:42,693 [main] DEBUG [org.springframework.orm.hibernate4.HibernateTransactionManager.doCleanupAfterCompletion()] Closing Hibernate Session [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=[] updates=[] deletions=[] collectionCreations=[] collectionRemovals=[] collectionUpdates=[] unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])] after transaction

更新:ログで、Hibernateトランザクションをロールバックしようとしていることに気付きました(ただし、これはJDBCです)。次に、「txManager」のクラスが現在org.springframework.orm.hibernate4.HibernateTransactionManagerであることに気付いたので、 org.springframework.jdbc.datasource.DataSourceTransactionManagerを試してみましたが、ロールバックが機能しました。したがって、私の問題は、より具体的には、HibernateとJDBCを使用するように構成する方法にあると思います...私はまだ何が悪いのかわかりません。

4

2 に答える 2

0

JUnitクラスとDAOクラスは問題ないようです。

問題は、トランザクションがロールバックされる前に接続が自動コミットされていることである可能性があります。dataSource Beanを変更して、 defaultAutoCommitプロパティを含めることができますか

<bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource">
      <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
      <property name="url" value="jdbc:oracle:thin:@SERVER:PORT:DB"/>
      <property name="username" value="USER"/>
      <property name="password" value="XXXXXX"/>
      <property name="defaultAutoCommit" value="false" /> 
</bean> 

これが機能しない場合は、コンソールログを貼り付けることができます。

于 2012-12-18T02:01:45.227 に答える
0

私の問題の解決策は、HibernateTransactionManagerのdataSourceを指定することでした。これがHibernateTransactionManagerのドキュメントです。

ですから、元の投稿で私がどのように定義したかを投稿しなかったのは間違いだったと思いtxManagerます。

  <bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="mySessionFactory"/>
  </bean>

変更:

  <bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
    <property name="sessionFactory" ref="mySessionFactory"/>
    <property name="dataSource" ref="dataSource" />
  </bean>

SessionFactory定義にも追加<property name="dataSource"><ref local="dataSource"/></property>しましたが、JdbcTemplateだけが気になる場合は必要ないようです。HQLがそこに混在している場合でも、それが必要だと思われます。

デバッグ印刷が機能しているときは、次のようになります。私が見た唯一の違いは、Returning JDBC Connection to DataSourceロールバックを開始する前にこの行がなかったことです

2012-12-19 08:14:29,455 [main] DEBUG [org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction()] Creating new transaction with name [com.company.group.spring.service.MyClassService.create]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''

2012-12-19 08:14:29,512 [main] DEBUG [org.springframework.orm.hibernate4.HibernateTransactionManager.doBegin()] Opened new Session [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=[] updates=[] deletions=[] collectionCreations=[] collectionRemovals=[] collectionUpdates=[] unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])] for Hibernate transaction

2012-12-19 08:14:29,514 [main] DEBUG [org.springframework.orm.hibernate4.HibernateTransactionManager.doBegin()] Preparing JDBC Connection of Hibernate Session [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=[] updates=[] deletions=[] collectionCreations=[] collectionRemovals=[] collectionUpdates=[] unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])]

2012-12-19 08:14:29,539 [main] DEBUG [org.springframework.orm.hibernate4.HibernateTransactionManager.doBegin()] Exposing Hibernate transaction as JDBC transaction [org.hibernate.engine.jdbc.internal.proxy.ConnectionProxyHandler@1289e48[valid=true]]

2012-12-19 08:14:29,558 [main] DEBUG [com.company.group.spring.dao.MyClassDAOImpl.insert()] Session Factory is: org.hibernate.internal.SessionFactoryImpl@1285252

2012-12-19 08:14:29,569 [main] DEBUG [org.springframework.jdbc.core.JdbcTemplate.update()] Executing prepared SQL update

2012-12-19 08:14:29,570 [main] DEBUG [org.springframework.jdbc.core.JdbcTemplate.execute()] Executing prepared SQL statement [insert into MY_CLASS (COL1, COL2, COL3, COL4, COL5, COL6, COL7, COL8, COL9) VALUES (?, ?, SYSDATE,?, ?, SYSDATE, ?,?, ?)]

2012-12-19 08:14:29,608 [main] DEBUG [org.springframework.jdbc.core.JdbcTemplate$2.doInPreparedStatement()] SQL update affected 1 rows

2012-12-19 08:14:29,611 [main] DEBUG [org.springframework.transaction.support.AbstractPlatformTransactionManager.processRollback()] Initiating transaction rollback

2012-12-19 08:14:29,612 [main] DEBUG [org.springframework.orm.hibernate4.HibernateTransactionManager.doRollback()] Rolling back Hibernate transaction on Session [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=[] updates=[] deletions=[] collectionCreations=[] collectionRemovals=[] collectionUpdates=[] unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])]

2012-12-19 08:14:29,680 [main] DEBUG [org.springframework.orm.hibernate4.HibernateTransactionManager.doCleanupAfterCompletion()] Closing Hibernate Session [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=[] updates=[] deletions=[] collectionCreations=[] collectionRemovals=[] collectionUpdates=[] unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])] after transaction
于 2012-12-19T16:29:02.310 に答える