【问题标题】:Transaction not rolling back in Spring Test for delete operation事务未在 Spring Test 中回滚以进行删除操作
【发布时间】:2011-07-03 19:52:26
【问题描述】:

在进行 Spring 测试时,不知何故我的测试没有回滚删除事务。数据被永久删除。 我正在使用 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");
        }

    }
}

我可以在控制台上看到消息“帐户再次为空”,它应该是。正如它在测试中一样。但是测试完成后。在数据库中,ID 为“87EDA29EBB65371CE04500144F54AB6D”的记录被永久删除!它应该在测试完成后回滚。我真的很困惑为什么交易没有回滚。

这是我的 testApplicationContext.xml 条目:

        <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>

【问题讨论】:

    标签: hibernate spring junit4 spring-test


    【解决方案1】:

    你的测试看起来很奇怪。 @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");
            }           
        }
    }
    

    另请参阅:

    【讨论】:

    • 完美!那是罪魁祸首。删除正在回滚。
    • 我的 testApplicationContext.xml 代理条目是否配置得当?虽然它们工作得很好,但我仍然认为应该有更好的方法来配置代理/拦截器。
    • @supernova:我对拦截器的手动配置不是很熟悉,因为我更喜欢注释驱动的方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-19
    • 2016-08-02
    • 1970-01-01
    • 1970-01-01
    • 2014-12-20
    相关资源
    最近更新 更多