Spring 事务单元测试 - Hibernate 查询不回滚

发布于 2024-09-09 07:17:14 字数 3048 浏览 2 评论 0原文

我正在使用 Spring 3 和 Hibernate 3.5,我没有让我的事务在测试环境中回滚,这让我担心它们也不会在生产中回滚。

测试类:

@ContextConfiguration(loader = MyConfigurationLoader.class)
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
public class DashTemplateRepositoryTest extends AbstractMulitpleDataSourceSpringContextTests {

    @Autowired
    DashTemplateRepository dashTemplateRepository;

    @Test
    public void testSaveCategory() {
        int initialCount = getCategoryCount();

        Category c = new Category();
        c.setName("mynewcategory");
        dashTemplateRepository.save(c);

        assertEquals(initialCount + 1, getCategoryCount());
    }
}

它扩展了自定义类:

public abstract class AbstractTransactionalTemplateTests extends AbstractTransactionalJUnit4SpringContextTests {

    protected SimpleJdbcTemplate simpleJdbcTemplate;

    @Autowired
    DashTemplateRepository dashTemplateRepository;

    @Resource(name = "dashDataSource")
    public void setDataSource(final DataSource dataSource) {
        this.simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);
    } ..snip...

更新:我需要执行 simpleJdbcTemplate 插入,因为我有多个数据源,并且默认情况下此测试类无法处理该问题,我无法找到 spring 支持的解决方案,但是春季论坛的一位贡献者发布了此解决方法。在我提取这个超类之前就存在回滚问题。我假设问题比这更基本,休眠似乎不知道事务管理器,有什么方法可以证明这一点?

数据源Bean:

<bean id="dashDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/dashtemplate"/>
        <property name="username" .../>
        <property name="password" .../>
    </bean>

我的Context-text.xml(简化,省略了其中一些)

<!-- Hibernate -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource" ref="dashDataSource" />
        <property name="annotatedClasses">
            <list>
                <value>com.dash.Category</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
            </props>
        </property>
    </bean>

    <bean id="dashTemplateRepository" class="com.wdp.DashTemplateRepositoryHibernateTemplateImpl">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>

    <tx:annotation-driven transaction-manager="transactionManager"/>
    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>

测试运行良好,我的对象被持久化,但它永远不会回滚,也没有出现任何错误

I am using Spring 3, and Hibernate 3.5, I am not getting my transactions to rollback in the test environment, which has me worried they would not be rolled back in production either.

Test Class:

@ContextConfiguration(loader = MyConfigurationLoader.class)
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
public class DashTemplateRepositoryTest extends AbstractMulitpleDataSourceSpringContextTests {

    @Autowired
    DashTemplateRepository dashTemplateRepository;

    @Test
    public void testSaveCategory() {
        int initialCount = getCategoryCount();

        Category c = new Category();
        c.setName("mynewcategory");
        dashTemplateRepository.save(c);

        assertEquals(initialCount + 1, getCategoryCount());
    }
}

Which extends a custom class :

public abstract class AbstractTransactionalTemplateTests extends AbstractTransactionalJUnit4SpringContextTests {

    protected SimpleJdbcTemplate simpleJdbcTemplate;

    @Autowired
    DashTemplateRepository dashTemplateRepository;

    @Resource(name = "dashDataSource")
    public void setDataSource(final DataSource dataSource) {
        this.simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);
    } ..snip...

UPDATE: I needed to do the simpleJdbcTemplate insertion because I have multiple dataSources, and by default this test class can't handle that, I wasn't able to find a spring supported solution, but on the spring forums a contributor posted this workaround. The rollback problem existed before I extracted this super class. I'm assuming the problem is more basic than that, hibernate doesn't seem to be aware of the transaction manager, is there any way I can prove that?

Datasource Bean:

<bean id="dashDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/dashtemplate"/>
        <property name="username" .../>
        <property name="password" .../>
    </bean>

My Context-text.xml (simplified, left out some of it)

<!-- Hibernate -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource" ref="dashDataSource" />
        <property name="annotatedClasses">
            <list>
                <value>com.dash.Category</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
            </props>
        </property>
    </bean>

    <bean id="dashTemplateRepository" class="com.wdp.DashTemplateRepositoryHibernateTemplateImpl">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>

    <tx:annotation-driven transaction-manager="transactionManager"/>
    <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>

The test runs fine, my object is persisted, but it is never rolled back, there doesn't appear to be any errors either

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

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

发布评论

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

评论(2

没企图 2024-09-16 07:17:14

问题是 MySQL 使用 MyISAM 而不是 InnoDB - MyISAM 不支持回滚

The problem was that MySQL was using MyISAM instead of InnoDB - rollbacks are not supported by MyISAM

北城半夏 2024-09-16 07:17:14

这就是我的基础测试类的样子,并且对我来说效果很好。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath*:/context.xml"})
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
@Transactional
public class BaseTest extends AbstractTransactionalJUnit4SpringContextTests {
//....
}

This is what my base test class looks like and works fine for me.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath*:/context.xml"})
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
@Transactional
public class BaseTest extends AbstractTransactionalJUnit4SpringContextTests {
//....
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文