2011-02-24 2 views
3

어떻게 든 스프링 테스트를 수행 할 때 내 테스트가 삭제 트랜잭션을 롤백하지 않습니다. 데이터가 영구적으로 삭제됩니다. Spring-Hibernate 콤보를 사용하고 있습니다.트랜잭션이 스프링에서 롤백되지 않습니다. 삭제 작업을 테스트합니다.

@RunWith(SpringJUnit4ClassRunner.class) 
@TestExecutionListeners({TransactionalTestExecutionListener.class, 
DependencyInjectionTestExecutionListener.class 
}) 
@ContextConfiguration(locations={"/testApplicationContext.xml"}) 
@TransactionConfiguration(defaultRollback=true) 
public class TestDummy { 

private ApplicationContext context; 

@Transactional 
private AccountManager getAccountManager() { 
    this.context = new ClassPathXmlApplicationContext("testApplicationContext.xml"); 
    return (AccountManager) context.getBean("accountManager"); 
} 



@Test 
@Transactional 
@Rollback(true) 
public void testDeleteAccount(){ 

     Account acc = getAccountManager().getAccountDaoHibernate().get("87EDA29EBB65371CE04500144F54AB6D"); 
     System.out.println("Account name is "+acc.getAccountName()); 
     getAccountManager().deleteAccountHard(acc); 
     Account acc1 = getAccountManager().getAccountDaoHibernate().get("87EDA29EBB65371CE04500144F54AB6D"); 
     if(acc1 != null){ 
     System.out.println("Now name is "+ acc1.getAccountName()); 
     }else{ 
      System.out.println("Account again is null"); 
     } 

    } 
} 

내가 콘솔에 메시지를 볼 수 있습니다 "계정을 다시 null 인"그것이 있어야한다 :

여기 내 테스트 클래스입니다. 그것으로 시험에서. 그러나 시험이 끝난 후에. 데이터베이스에서 ID가 "87EDA29EBB65371CE04500144F54AB6D"인 레코드는 영구적으로 삭제됩니다. 테스트가 끝난 후 롤백해야합니다. 트랜잭션이 왜 돌아 가지 않는지 나는 정말로 혼란 스럽습니다.

 <bean id="accountManager" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> 
      <property name="target"><ref local="accountManagerTarget"/></property> 
      <property name="transactionManager"><ref local="transactionManager"/></property> 
        <property name="transactionAttributes"> 
        <props> 
          <!-- Avoid PROPAGATION_REQUIRED !! It could kill your performances by generating a new transaction on each request !! --> 

          <prop key="get*">PROPAGATION_SUPPORTS,readOnly</prop> 
          <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop> 
          <prop key="load*">PROPAGATION_REQUIRED,readOnly</prop> 
          <prop key="add*">PROPAGATION_REQUIRED</prop> 
          <prop key="del*">PROPAGATION_REQUIRED</prop> 

        </props> 
      </property> 
      <property name="preInterceptors"> 
       <list> 
        <ref bean="hibernateInterceptor"/> 
       </list> 
      </property>   

    </bean> 


<bean id="accountManagerTarget" 
      class="com.db.spgit.abstrack.manager.AccountManager"> 
    <property name="accountDaoHibernate" ref="accountDaoHibernate" /> 
</bean> 


<bean id="sessionFactory" 
    class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> 
    <property name="configurationClass"> 
     <value>org.hibernate.cfg.AnnotationConfiguration</value> 
    </property> 
    <property name="configLocation"> 
     <value>classpath:hibernate-test.cfg.xml</value> 
    </property> 
</bean> 

<bean id="hibernateInterceptor" class="org.springframework.orm.hibernate3.HibernateInterceptor"> 
    <property name="sessionFactory">  
     <ref bean="sessionFactory"/> 
    </property> 
</bean> 


<bean id="hibernateTemplate" 
    class="org.springframework.orm.hibernate3.HibernateTemplate"> 
    <property name="sessionFactory" ref="sessionFactory" /> 
</bean> 

답변

4

귀하의 테스트가 절대적으로 이상한 같습니다

여기 내 testApplicationContext.xml 항목입니다. @ContextConfiguration은 이미 응용 프로그램 컨텍스트를로드하므로 수동으로 수행 할 필요가 없습니다.

다음 코드는 예상대로 작동합니다 :

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations={"/testApplicationContext.xml"}) 
@TransactionConfiguration(defaultRollback=true) 
public class TestDummy { 
    @Autowired 
    private AccountManager accountManager; 

    @Test 
    @Transactional 
    public void testDeleteAccount(){   
     Account acc = accountManager.getAccountDaoHibernate().get("87EDA29EBB65371CE04500144F54AB6D"); 
     System.out.println("Account name is "+acc.getAccountName()); 
     accountManager.deleteAccountHard(acc); 
     Account acc1 = accountManager.getAccountDaoHibernate().get("87EDA29EBB65371CE04500144F54AB6D"); 
     if(acc1 != null){ 
      System.out.println("Now name is "+ acc1.getAccountName()); 
     }else{ 
      System.out.println("Account again is null"); 
     }   
    } 
} 

항목 :

+0

완벽! 그것은 범인이었다. 삭제가 지금 롤백 중입니다. – supernova

+0

프록시 용 내 testApplicationContext.xml 항목이 이상적으로 구성 되었습니까? 그들은 잘 작동하지만 여전히 프록시/인터셉터를 구성하는 더 좋은 방법이 있어야한다고 생각합니다. – supernova

+0

@supernova : 필자는 주석 중심 방식을 선호하기 때문에 인터셉터 수동 구성에 익숙하지 않습니다. – axtavt