2014-05-04 130 views
0

我想单元测试一些持久代码,并遇到数据库挂在以前测试中创建的行上的问题。我也在使用Hibernate Search,尽管这并不反映在我在这里分享的代码中。Junit测试在事务后不回滚

我使用Spring 3.1.X,休眠4.x和HSQLDB 2.3.2

登录

DEBUG - HibernateTransactionManager.doGetTransaction(290) | Found thread-bound Session [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=[] updates=[] deletions=[] orphanRemovals=[] collectionCreations=[] collectionRemovals=[] collectionUpdates=[] collectionQueuedOps=[] unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])] for Hibernate transaction 
    DEBUG - AbstractPlatformTransactionManager.handleExistingTransaction(470) | Participating in existing transaction 
    Hibernate: insert into UserRole (userRoleId, label) values (default, ?) 
    DEBUG - HibernateTransactionManager.doGetTransaction(290) | Found thread-bound Session [SessionImpl(PersistenceContext[entityKeys=[EntityKey[nl.project.model.user.UserRole#1]],collectionKeys=[]];ActionQueue[insertions=[] updates=[] deletions=[] orphanRemovals=[] collectionCreations=[] collectionRemovals=[] collectionUpdates=[] collectionQueuedOps=[] unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])] for Hibernate transaction 
    DEBUG - AbstractPlatformTransactionManager.handleExistingTransaction(470) | Participating in existing transaction 
    Hibernate: insert into UserRole (userRoleId, label) values (default, ?) 

    ***First test**** 

    DEBUG - AbstractPlatformTransactionManager.processRollback(843) | Initiating transaction rollback 
    DEBUG - HibernateTransactionManager.doRollback(496) | Rolling back Hibernate transaction on Session [SessionImpl(PersistenceContext[entityKeys=[EntityKey[nl.project.model.user.User#1],EntityKey[nl.project.model.user.UserRole#1],EntityKey[nl.project.model.user.UserRole#2], EntityKey[nl.project.model.user.UserRole#3]],collectionKeys=[CollectionKey[nl.project.model.user.User.roles#1]]];ActionQueue[insertions=[] updates=[] deletions=[] orphanRemovals=[] collectionCreations=[] collectionRemovals=[] collectionUpdates=[] collectionQueuedOps=[] unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])] 
    DEBUG - HibernateTransactionManager.doBegin(342) | Opened new Session [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=[] updates=[] deletions=[] orphanRemovals=[] collectionCreations=[] collectionRemovals=[] collectionUpdates=[] collectionQueuedOps=[] unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])] for Hibernate transaction 
    DEBUG - HibernateTransactionManager.doBegin(352) | Preparing JDBC Connection of Hibernate Session [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=[] updates=[] deletions=[] orphanRemovals=[] collectionCreations=[] collectionRemovals=[] collectionUpdates=[] collectionQueuedOps=[] unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])] 
    DEBUG - HibernateTransactionManager.doBegin(413) | Exposing Hibernate transaction as JDBC transaction [[email protected]] 
    DEBUG - HibernateTransactionManager.doGetTransaction(290) | Found thread-bound Session [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=[] updates=[] deletions=[] orphanRemovals=[] collectionCreations=[] collectionRemovals=[] collectionUpdates=[] collectionQueuedOps=[] unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])] for Hibernate transaction 
    DEBUG - AbstractPlatformTransactionManager.handleExistingTransaction(470) | Participating in existing transaction 
    DEBUG - HibernateTransactionManager.doGetTransaction(290) | Found thread-bound Session [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=[] updates=[] deletions=[] orphanRemovals=[] collectionCreations=[] collectionRemovals=[] collectionUpdates=[] collectionQueuedOps=[] unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])] for Hibernate transaction 
    DEBUG - AbstractPlatformTransactionManager.handleExistingTransaction(470) | Participating in existing transaction 
    DEBUG - HibernateTransactionManager.doGetTransaction(290) | Found thread-bound Session [SessionImpl(PersistenceContext[entityKeys=[],collectionKeys=[]];ActionQueue[insertions=[] updates=[] deletions=[] orphanRemovals=[] collectionCreations=[] collectionRemovals=[] collectionUpdates=[] collectionQueuedOps=[] unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])] for Hibernate transaction 
    DEBUG - AbstractPlatformTransactionManager.handleExistingTransaction(470) | Participating in existing transaction 
    Hibernate: select this_.userRoleId as userRole1_92_0_, this_.label as label2_92_0_ from UserRole this_ 
    DEBUG - HibernateTransactionManager.doGetTransaction(290) | Found thread-bound Session [SessionImpl(PersistenceContext[entityKeys=[EntityKey[nl.project.model.user.UserRole#3], EntityKey[nl.project.model.user.UserRole#2], EntityKey[nl.project.model.user.UserRole#1]],collectionKeys=[]];ActionQueue[insertions=[] updates=[] deletions=[] orphanRemovals=[] collectionCreations=[] collectionRemovals=[] collectionUpdates=[] collectionQueuedOps=[] unresolvedInsertDependencies=UnresolvedEntityInsertActions[]])] for Hibernate transaction 
    DEBUG - AbstractPlatformTransactionManager.handleExistingTransaction(470) | Participating in existing transaction 
    Hibernate: insert into UserRole (userRoleId, label) values (default, ?) 
    WARN - SqlExceptionHelper.logExceptions(144) | SQL Error: -104, SQLState: 23505 
    ERROR - SqlExceptionHelper.logExceptions(146) | integrity constraint violation: unique constraint or index violation; UK_O0VIK8LBO8UYMR8WUDN5T21QX table: USERROLE 

代码

@Entity 
@Immutable 
@Table 
@NaturalIdCache(region=CacheRegion.NATURAL) 
@Cache(usage=CacheConcurrencyStrategy.NONSTRICT_READ_WRITE,region=CacheRegion.USER) 
public class UserRole implements Serializable{ 

    public static final String ROLE_ANONYMOUS="ROLE_ANONYMOUS"; 
    public static final String ROLE_USER="ROLE_USER"; 
    public static final String ROLE_PROVENDOR="ROLE_PROVENDOR"; 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(nullable=false, updatable=false) 
    private Long id; 

    @Column(nullable=false,unique=true,updatable=false) 
    @NaturalId 
    private String label; 

    ... 
    } 

代码

public class CoreTest extends TestCase { 

     @Inject 
     protected SimpleManager<Long> simpleMgr; 

     public void baseSetup(){ 

      simpleMgr.flush(); 
          simpleMgr.clear(); 

        //after 1st test this contains all created UserRoles 
      List roles = simpleMgr.getAll(UserRole.class); 

      UserRole role = new UserRole(UserRole.ROLE_ANONYMOUS); 
      simpleMgr.save(role); 

      role = new UserRole(UserRole.ROLE_USER); 
      simpleMgr.save(role); 
     } 
    } 

    @RunWith(SpringJUnit4ClassRunner.class) 
    @ContextConfiguration(locations = { 
      "classpath:/spring/applicationContext.xml" 
      "classpath:/spring/applicationContext-transaction.xml"}) 
    public class MyManagerTest extends CoreTest{ 

     @Before 
     public void methodSetup(){ 

      super.baseSetup(); 

      role = new UserRole(UserRole.ROLE_PROUSER); 
      simpleMgr.save(role); 

      simpleMgr.save(userMgr.createUser("marc", "[email protected]")); 

      simpleMgr.flush(); 
     } 

     @Test 
     @Transactional 
     public void test1(){ 
      ... 
     } 

     @Test 
     @Transactional 
     public void test2(){ 
      .... 
     } 

交易管理

<bean id="dataSource" class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy"> 
     <property name="targetDataSource" ref="mainDataSource"/> 
    </bean> 

    <bean id="mainDataSource" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close"> 
     <property name="driverClass" value="${jdbc.driverClassName}"/> 
     [...] 
    </bean> 
    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> 
     <property name="dataSource" ref="dataSource"/> 
     <property name="configLocation" value="classpath:hibernate.cfg.xml"/> 
     <property name="hibernateProperties"> 
      <value> 
       hibernate.connection.driver_class=${jdbc.driverClassName} 
       hibernate.jdbc.batch_size=30 
       hibernate.dialect=${hibernate.dialect} 
       hibernate.connection.autoReconnect=true 
       hibernate.connection.autoReconnectForPools=true 
       hibernate.connection.autocommit=false 
      </value> 
     </property> 
    </bean> 
    <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> 
     <property name="sessionFactory" ref="sessionFactory"/> 
    </bean> 
+0

尝试在您的测试中添加“@Rollback(true)”注释。 –

+0

谢谢。没有区别 – Marc

+0

可能是因为你没有清理你的数据? –

回答

0

尝试增加事务拦截器:

<beans xmlns:tx="http://www.springframework.org/schema/tx" 
    xsi:schemaLocation=" 
    ... 
    http://www.springframework.org/schema/tx 
    http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> 
    <tx:annotation-driven transaction-manager="transactionManager"/> 
</beans> 
+0

这是在那里,我没有在例子中包括这个 – Marc

0

扩展AbstractTransactionalJunit4SpringContextTests或添加@TestExecutionListeners(TransactionalTestExecutionListener.class)。

+0

不知道这是否会有帮助,因为它只是一个便利的类,我已经在过去由于缺少@TestExecutionListeners(TransactionalTestExecutionListener.class)而遇到了问题 – Marc

+0

。 – Alexander

+0

顺便说一句,你扩展TestCase - 你使用的是什么版本的junit? (在Junit4中不需要扩展任何东西)。 – Alexander

0

所以,我最终通过在BoneCPDatasource上指定defaultAutoCommit = false来得到这个工作。 AFAIK对于这种配置来说这太低了,因此可能是错误的。但至少它工作。

相关问题