为什么Spring数据存储库上的getOne(…)不会抛出EntityNotFoundException?
我正在处理一个奇怪的问题,我正在进行集成测试,调用我的控制器从数据库中获取一个不存在的对象。
public Optional get(Long id) { try { return Optional.ofNullable(repository.getOne(id)); } catch(EntityNotFoundException e) { return Optional.empty(); } }
当getOne(…)
无法找到任何东西时,我期待一个EntityNotFoundException
但实际上什么都没有。 如果我检查我的结果,我可以看到我有一个带有处理程序链接的空实体“抛出EntityNotFoundException
”但是我们不进入catch并返回这个奇怪实体的可选项。
我无法理解这种行为。
这是由于JPA指定EntityManager.getReference(…)
工作的方式。 它应该返回一个代理,它将解析在第一次访问属性时返回的对象,或者最终抛出包含的exception。
解决这个问题的最简单方法是简单地使用findOne(…)
,就像使用Optional.ofNullable(repository.findOne(…))
。 如果没有找到结果, findOne(…)
将返回null
。
解决此问题的更高级方法是使存储库直接返回Optional
实例。 这可以通过使用Optional
创建自定义基本存储库接口作为find…
-methods的返回类型来实现。
interface BaseRepository extends Repository { Optional findOne(ID id); // declare additional methods if needed } interface YourRepository extends BaseRepository { … }
在Spring Data示例存储库中找到完整的示例。
这就是它对我有用的方式
public User findUserById(Long id) { return userRepository.findById(id).orElse(null); }