spring数据测试存储库

gijlo24d  于 2021-08-25  发布在  Java
关注(0)|答案(1)|浏览(406)

下面是一个测试类:

@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 从这个方法来看,测试效果很好。

baubqpgj

baubqpgj1#

你所处的环境很难理解,因为你只提供了一些摘录!但从我所看到的我猜。。。
如果您使用 @Transactional ,每个测试方法都包含一个新事务,该事务在执行测试方法后自动回滚。
如果您现在在测试方法中准备了一些数据,那么它在隐式创建的事务的范围中是可见的。如果随后调用服务方法,并且此服务方法希望有一个新事务,则此新事务不会“看到”您在外部事务中准备的数据。如果您删除 @Transactional 通过服务方法的注解,存储库现在可以“查看”数据。
如果您查看了 Propagation enum,你会看到的 PROPAGATION_REQUIRES_NEW 按以下方式描述:

Create a new transaction, and suspend the current transaction if one exists.

问题是,为什么即使已经存在新的交易,他们也需要新的交易?如果还没有可用的,他们不能创建一个新的,但是如果已经存在,就使用现有的吗?这就是美国的情况 SUPPORTS 传播,默认情况下在 @Transactional 注解。

相关问题