繁体   English   中英

为什么Spring数据存储库上的getOne(...)不会抛出EntityNotFoundException?

[英]Why does getOne(…) on a Spring Data repository not throw an EntityNotFoundException?

我正在处理一个奇怪的问题,我正在进行集成测试,调用我的控制器从数据库中获取一个不存在的对象。

public Optional<T> get(Long id) {

  try {
    return Optional.ofNullable(repository.getOne(id));
  } catch(EntityNotFoundException e) {
    return Optional.empty();
  }
}

getOne(…)无法找到任何东西时,我期待一个EntityNotFoundException但实际上什么都没有。 如果我检查我的结果,我可以看到我有一个带有处理程序链接的空实体“抛出EntityNotFoundException ”但是我们没有进入catch并返回这个奇怪实体的可选项。

我无法理解这种行为。

这是由于JPA指定EntityManager.getReference(…)的工作方式。 它应该返回一个代理,它将在第一次访问属性时解析要返回的对象,或者最终抛出包含的异常。

解决此问题的最简单方法是简单地使用findOne(…) ,例如Optional.ofNullable(repository.findOne(…)) 如果没有找到结果, findOne(…)将返回null

解决此问题的更高级方法是使存储库直接返回Optional实例。 这可以通过使用Optional<T>创建自定义基本存储库接口作为find… -methods的返回类型来实现。

interface BaseRepository<T, ID extends Serializable> extends Repository<T, ID> {

  Optional<T> findOne(ID id);

  // declare additional methods if needed
}

interface YourRepository extends BaseRepository<DomainClass, Long> { … }

Spring Data示例存储库中找到完整的示例。

在Spring @Repository班, getOne(id)的方法并不总是验证存在,直到该对象被查询(通过调用entity.getId()或东西),所以它没有这样的实体例外可能会被延迟。 要立即验证,请改用findById(id) (它返回一个Optional<EntityType> ,如果具有该id的实体不存在,它将为空)。


这就是它对我有用的方式

public User findUserById(Long id) {
    return userRepository.findById(id).orElse(null);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM