为什么Spring数据存储库上的getOne(...)不会抛出EntityNotFoundException? [英] Why does getOne(…) on a Spring Data repository not throw an EntityNotFoundException?
问题描述
我正在处理一个奇怪的问题,我正在进行集成测试,调用我的控制器从数据库中获取一个不存在的对象。
I'm working on a weird issue, I was doing integration testing, calling my controller to get an object from database that doesn't exist.
public Optional<T> get(Long id) {
try {
return Optional.ofNullable(repository.getOne(id));
} catch(EntityNotFoundException e) {
return Optional.empty();
}
}
当 getOne(...)时
无法找到任何内容,我期待 EntityNotFoundException
但实际上什么都没有。如果我检查我的结果,我可以看到我有一个带有处理程序链接的空实体抛出 EntityNotFoundException
但是我们没有进入捕获并返回可选的这个奇怪的实体。
When getOne(…)
is not able to find anything, I was expecting an EntityNotFoundException
but actually nothing. If I inspect my result I can see that I have an empty entity with a handler link to it "threw EntityNotFoundException
" but we don't go in the catch and I return an optional of this weird entity.
我无法理解这种行为。
推荐答案
这是由于JPA指定 EntityManager.getReference(...)
的方式。它应该返回一个代理,它将在第一次访问属性时解析要返回的对象,或者最终抛出包含的异常。
This is due to the way JPA specifies EntityManager.getReference(…)
to work. It's supposed to return a proxy that will either resolve the object to be returned on the first access of a property or throw the contained exception eventually.
最简单的解决方法这只是简单地使用 findOne(...)
,就像这样 Optional.ofNullable(repository.findOne(...))
。 findOne(...)
将返回 null
,以防未找到结果。
The easiest way to work around this is to simply use findOne(…)
instead, like this Optional.ofNullable(repository.findOne(…))
. findOne(…)
will return null
in case no result is found.
更高级的解决方法是使存储库直接返回 Optional
实例。这可以通过使用 Optional< T>
创建自定义基本存储库接口作为 find ...
的返回类型来实现 - 方法。
A more advanced way of resolving this is to make the repository return Optional
instances directly. This can be achieved by creating a custom base repository interface using Optional<T>
as return type for the 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 examples repository 。
这篇关于为什么Spring数据存储库上的getOne(...)不会抛出EntityNotFoundException?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!