如何测试存储库中标记为@Modifying的方法?

And*_*r1i 2 java junit spring-data-jpa

例如我有

public interface CrudUserRepository extends JpaRepository<User, Integer> {

@Modifying
@Query(nativeQuery = true, value = "UPDATE users SET active=?2 WHERE id=?1")
void setActive(long id, boolean active);
}
Run Code Online (Sandbox Code Playgroud)

在我的测试中,我调用这个方法,然后通过 id 查找。

@Autowired
CrudUserRepository crudUser;
@Transactional
@Test
public void setActiveTest(){
    User user = getUser();
    crudUser.save(user);

    crudUser.setActive(user.getId(), true);
    Optional<User> optUser = crudUser.findById(user.getId());
    assert optUser.get().isActive(); //here my test falls
Run Code Online (Sandbox Code Playgroud)

当我执行时,crudUser.findById(user.getId())我的 optUser 包含该用户不活动,但实际上他是活动的(我已经通过设置 @Rollback(false) 并手动检查数据库进行了测试)。

我如何测试这个案例?

RJ.*_*ang 7

因为crudUser.save会缓存实体。当您调用 时crudUser.findById,JPA 只是从缓存中获取实体,而不是从数据库中获取。crudUser.setActive不更新entity.active缓存中的。更改代码如下所示可以修复它(清除JPA缓存):

....
@PersistenceContext
EntityManager entityManager;
...
@Test
public void setActiveTest(){
  ...

  // clear the cache and force crudUser.findById from database
  entityManager.clear();

  Optional<User> optUser = crudUser.findById(user.getId());
  ...
}
Run Code Online (Sandbox Code Playgroud)