[英]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.SharedEntityManagerCreator
的JavaDocs 。 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
方法flush
, merge
, persist
, refresh
和remove
需要在事务内运行。 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.EXTENDED
或PersistenceContextType.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.