Spring 具有传播设置的数据测试存储库
Spring Data test repository with propagation setting
这是一个测试class:
@SpringBootTest
@AutoConfigureMockMvc
@Transactional
public class ValidationTest {
@Autowired
private EntityManager entityManager
...
}
我想测试服务:
@Transactional(propagation = Propagation.REQUIRES_NEW)
public boolean isEmailUnique(String emailAddress) {
Optional<User> user = userRepository.findByEmail(emailAddress);
...
}
为此,我创建并保存了一个实体:
entityManager.persist(new User(name: "abc", email: "abc@email.com"))
entityManager.flush()
最后调用请求:
mockMvc.perform(post("..."))
userRepository.findByEmail()
没有看到插入的实体,我错过了什么?
ps:如果我从方法中删除 @Transactional
,那么测试工作正常。
你所处的环境很难理解,因为你只提供了一些片段!但据我所见,我猜...
如果您使用 @Transactional
注释您的测试,每个测试方法都包含一个新的事务,该事务在测试方法执行后自动回滚。
如果您现在在测试方法中准备一些数据,那么它在隐式创建事务的范围内是可见的。如果你然后调用你的服务方法,这个服务方法想要有一个新的事务,这个新的事务不会'see'你在外部事务中准备的数据。如果从服务方法中删除 @Transactional
注释,存储库现在可以 'see' 数据。
如果您查看 Propagation
枚举的 javadoc,您会发现 PROPAGATION_REQUIRES_NEW
是这样描述的:
Create a new transaction, and suspend the current transaction if one exists.
问题是,为什么他们一定需要 new 交易,即使交易已经存在?如果 none 可用,他们就不能创建一个新的,但如果已经存在就使用现有的吗? SUPPORTS
传播就是这种情况,默认情况下在 @Transactional
注释上配置。
这是一个测试class:
@SpringBootTest
@AutoConfigureMockMvc
@Transactional
public class ValidationTest {
@Autowired
private EntityManager entityManager
...
}
我想测试服务:
@Transactional(propagation = Propagation.REQUIRES_NEW)
public boolean isEmailUnique(String emailAddress) {
Optional<User> user = userRepository.findByEmail(emailAddress);
...
}
为此,我创建并保存了一个实体:
entityManager.persist(new User(name: "abc", email: "abc@email.com"))
entityManager.flush()
最后调用请求:
mockMvc.perform(post("..."))
userRepository.findByEmail()
没有看到插入的实体,我错过了什么?
ps:如果我从方法中删除 @Transactional
,那么测试工作正常。
你所处的环境很难理解,因为你只提供了一些片段!但据我所见,我猜...
如果您使用 @Transactional
注释您的测试,每个测试方法都包含一个新的事务,该事务在测试方法执行后自动回滚。
如果您现在在测试方法中准备一些数据,那么它在隐式创建事务的范围内是可见的。如果你然后调用你的服务方法,这个服务方法想要有一个新的事务,这个新的事务不会'see'你在外部事务中准备的数据。如果从服务方法中删除 @Transactional
注释,存储库现在可以 'see' 数据。
如果您查看 Propagation
枚举的 javadoc,您会发现 PROPAGATION_REQUIRES_NEW
是这样描述的:
Create a new transaction, and suspend the current transaction if one exists.
问题是,为什么他们一定需要 new 交易,即使交易已经存在?如果 none 可用,他们就不能创建一个新的,但如果已经存在就使用现有的吗? SUPPORTS
传播就是这种情况,默认情况下在 @Transactional
注释上配置。