下面是一个测试类:
@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
从这个方法来看,测试效果很好。
1条答案
按热度按时间baubqpgj1#
你所处的环境很难理解,因为你只提供了一些摘录!但从我所看到的我猜。。。
如果您使用
@Transactional
,每个测试方法都包含一个新事务,该事务在执行测试方法后自动回滚。如果您现在在测试方法中准备了一些数据,那么它在隐式创建的事务的范围中是可见的。如果随后调用服务方法,并且此服务方法希望有一个新事务,则此新事务不会“看到”您在外部事务中准备的数据。如果您删除
@Transactional
通过服务方法的注解,存储库现在可以“查看”数据。如果您查看了
Propagation
enum,你会看到的PROPAGATION_REQUIRES_NEW
按以下方式描述:问题是,为什么即使已经存在新的交易,他们也需要新的交易?如果还没有可用的,他们不能创建一个新的,但是如果已经存在,就使用现有的吗?这就是美国的情况
SUPPORTS
传播,默认情况下在@Transactional
注解。