Spring Test 中事务未回滚删除操作

发布于 2024-10-19 11:55:15 字数 3824 浏览 8 评论 0原文

不知何故,我的测试在进行 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>

Somehow my test is not rolling back the delete transaction when doing a Spring Test. The data is deleted permanently.
I am using Spring-Hibernate combo.

here is my test class:

@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");
        }

    }
}

I can see the message on console "Account again is null " which it should be. As its with in the test. But After test is finished. In database the record with id "87EDA29EBB65371CE04500144F54AB6D" is deleted permanently!. It should roll back after test is done. I am really confused why transactions are not rolling back.

Here is my testApplicationContext.xml entries:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

绅刃 2024-10-26 11:55:15

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

另请参阅:

Your test looks absolutely weird. @ContextConfiguration already loads application context, you don't need to do it manually.

The following code should work as expected:

@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");
        }           
    }
}

See also:

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文