繁体   English   中英

如何在Spring中创建非事务性JUnit集成测试?

[英]How to create non-transactional JUnit integration tests in Spring?

集成测试类的注释为:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = IntegrationTestConfig.class)

它不应该在事务中运行,因此标记为@Transactional但是在尝试对EntityManager进行持久化,合并等操作时遇到错误,这是使用@PersistenceContext注入的:

没有可用的事务性EntityManager

如何解决?

编辑:根据注释中的要求,Spring版本为4.1.0.RELEASE和IntegrationTestConfig如下:

@EnableAspectJAutoProxy
@EnableAsync
@EnableScheduling
@EnableTransactionManagement
@Configuration
public class IntegrationTestConfig {
    /**
     * Override the existing JPA data source bean with a test data source.
     * @return test data source
     */
    @Bean
    public DataSource dataSource() {
        final SimpleDriverDataSource dataSource = new SimpleDriverDataSource();
        dataSource.setDriverClass(org.h2.Driver.class);
        dataSource.setUrl("jdbc:h2:mem:test;MODE=MySQL;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;INIT=CREATE SCHEMA IF NOT EXISTS mydb");
        dataSource.setUsername("sa");
        dataSource.setPassword("");
        return dataSource;
    }
}

如果确定您永远不会调用entityManager.flush() ,请按以下方式获取PersistenceContext

@PersistenceContext(type = PersistenceContextType.EXTENDED)
private EntityManager entityManager;

为什么需要这个? 当使用@PersistenceContext批注(不带任何属性)时,Spring Data JPA会分发所谓的共享EntityManager 有关这方面的完整详细信息,请参见org.springframework.orm.jpa.SharedEntityManagerCreatorJavaDocs 此类维护一个查找表,其中EntityManager方法flushmergepersistrefreshremove需要在事务内运行。 因此,每当遇到不在事务内部的方法调用时,它都会失败。

注释@PersistenceContext具有type属性,可以将其设置为PersistenceContextType.EXTENDEDPersistenceContextType.TRANSACTION ,默认值为后者。 因此,默认的@PersistenceContext导致SharedEntityManagerCreator查找事务,如果找不到任何事务,则进行纾困。

使用PersistenceContextType.EXTENDED可以避免在获取EntityManager时检查事务的需要,因此代码应该可以工作。


如果没有事务,仍然无法调用flush因为JPA提供程序要求仅在事务上下文中调用它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM