简体   繁体   English

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

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

An integration test class is annotated with: 集成测试类的注释为:

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

It's not supposed to run in a transaction so isn't marked as @Transactional but I'm getting errors when trying to perform persist, merge etc. operations on the EntityManager , which is injected using @PersistenceContext : 它不应该在事务中运行,因此标记为@Transactional但是在尝试对EntityManager进行持久化,合并等操作时遇到错误,这是使用@PersistenceContext注入的:

No transactional EntityManager available 没有可用的事务性EntityManager

How can this be resolved? 如何解决?

EDIT: As requested in the comments, the Spring version is 4.1.0.RELEASE and IntegrationTestConfig is below: 编辑:根据注释中的要求,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;
    }
}

If you are sure that you are never going to call entityManager.flush() , obtain the PersistenceContext as follows: 如果确定您永远不会调用entityManager.flush() ,请按以下方式获取PersistenceContext

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

Why is this needed? 为什么需要这个? Spring Data JPA hands out what is called a shared EntityManager when the @PersistenceContext annotation is used (without any attributes). 当使用@PersistenceContext批注(不带任何属性)时,Spring Data JPA会分发所谓的共享EntityManager Full details for this are available in the JavaDocs for org.springframework.orm.jpa.SharedEntityManagerCreator . 有关这方面的完整详细信息,请参见org.springframework.orm.jpa.SharedEntityManagerCreatorJavaDocs This class maintains a lookup table where the EntityManager methods flush , merge , persist , refresh and remove are required to be run inside a transaction. 此类维护一个查找表,其中EntityManager方法flushmergepersistrefreshremove需要在事务内运行。 So, any time it encounters a method call that is not inside a transaction, it bails out. 因此,每当遇到不在事务内部的方法调用时,它都会失败。

The annotation @PersistenceContext has a type attribute that can be set to one of PersistenceContextType.EXTENDED or PersistenceContextType.TRANSACTION , with the later being the default. 注释@PersistenceContext具有type属性,可以将其设置为PersistenceContextType.EXTENDEDPersistenceContextType.TRANSACTION ,默认值为后者。 Therefore, the default @PersistenceContext causes SharedEntityManagerCreator to look for a transaction and bail out if none is found. 因此,默认的@PersistenceContext导致SharedEntityManagerCreator查找事务,如果找不到任何事务,则进行纾困。

Using PersistenceContextType.EXTENDED bypasses the need to check for a transaction when obtaining the EntityManager and therefore the code should work. 使用PersistenceContextType.EXTENDED可以避免在获取EntityManager时检查事务的需要,因此代码应该可以工作。


flush still cannot be called without a transaction because the JPA providers require it to be called only within a transactional context. 如果没有事务,仍然无法调用flush因为JPA提供程序要求仅在事务上下文中调用它。

暂无
暂无

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

相关问题 运行集成测试后如何删除非事务性数据库日志记录? - How to remove non-transactional database logging after running integration tests? Java Spring:mongodb的事务版本和非事务版本的兼容性 - Java Spring: Compatibility for both transactional and non-transactional versions of mongodb 例外-非交易 - Exception - non-transactional 如何从事务方法调用非事务方法 - How to call non-transactional methods from a Transactional method Spring 3 MVC Hibernate 3.5.4 hibernateTemplate没有关闭连接(非事务性) - Spring 3 MVC Hibernate 3.5.4 hibernateTemplate not closing connections (non-transactional) Spring Boot-从非事务性原因更新中校准事务性方法 - Spring Boot - caling transactional method from non-transactional cause update 在另一个实例中从事务方法调用 spring 非事务方法时,事务是否得到传播? - When calling a spring Non-Transactional method from a Transactional Method in another instance, does the transaction get propagated? 如何重构@Transactional方法来拆分非事务性部分 - How do you refactor a @Transactional method to split out non-transactional parts 如何在相同和不同服务中调用@Transactional和non-Transactional方法时回滚事务? - How to rollback transaction on calling @Transactional and non-Transactional method in same and different Service? 非事务命令关闭OrienttDB中的数据库 - Non-Transactional Commands Closes Database in OrienttDB
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM