Java Spring Data JPA findOne() 更改为 Optional 如何使用?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/49316751/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Spring Data JPA findOne() change to Optional how to use this?
提问by Hulk Choi
I'm learning SpringBoot2.0
with Java8
.
我正在学习SpringBoot2.0
用Java8
。
And I followed some blog-making tutorial example.
我遵循了一些博客制作教程示例。
The tutorial source code is:
教程源代码为:
@GetMapping("/{id}/edit")
public String edit(@PathVariable Long id, Model model) {
model.addAttribute("categoryDto", categoryService.findOne(id));
return "category/edit";
}
But this code is throwing this error:
但是这段代码抛出了这个错误:
categoryService.findOne(id)
categoryService.findOne(id)
I'm thinking about changing the JPA findOne()
method to Optional< S >
我正在考虑将 JPAfindOne()
方法更改为Optional< S >
How to solve that?
如何解决?
More info:
更多信息:
This is the categoryService method:
这是 categoryService 方法:
public Category findOne(Long id) {
return categoryRepository.findOne(id);
}
采纳答案by davidxxx
From at least, the 2.0
version, Spring-Data-Jpa
modified findOne()
.
Now, findOne()
doesn't have both the same signature and the same behavior.
Previously, it was defined in the CrudRepository
interface as :
至少从2.0
版本,Spring-Data-Jpa
修改findOne()
。
现在,findOne()
没有相同的签名和相同的行为。
以前,它在CrudRepository
接口中定义为:
T findOne(ID primaryKey);
Now, the single findOne()
method that you will find in CrudRepository
is which one defined in the QueryByExampleExecutor
interface as :
现在,findOne()
您将找到的单一方法CrudRepository
是QueryByExampleExecutor
接口中定义的方法:
<S extends T> Optional<S> findOne(Example<S> example);
That is implemented finally by SimpleJpaRepository
, the default implementation of the CrudRepository
interface.
This method is a query by example search and you don't want to that as replacement.
这最终由接口SimpleJpaRepository
的默认实现实现CrudRepository
。
此方法是按示例搜索查询,您不希望将其作为替代。
In fact, the method with the same behavior is still there in the new API but the method name has changed.
It was renamed from findOne()
to findById()
in the CrudRepository
interface :
实际上,具有相同行为的方法仍然存在于新 API 中,但方法名称已更改。
它是从更名findOne()
到findById()
的CrudRepository
接口:
Optional<T> findById(ID id);
Now it returns an Optional
. Which is not so bad to prevent NullPointerException
.
现在它返回一个Optional
. 这不是那么糟糕,可以防止NullPointerException
。
So, the actual method to invoke is now Optional<T> findById(ID id)
.
因此,调用的实际方法是 now Optional<T> findById(ID id)
。
How to use that ?
Learning Optional
usage.
Here important information about its specification :
怎么用那个?
学习Optional
使用。以下是有关其规格的重要信息:
A container object which may or may not contain a non-null value. If a value is present, isPresent() will return true and get() will return the value.
Additional methods that depend on the presence or absence of a contained value are provided, such as orElse() (return a default value if value not present) and ifPresent() (execute a block of code if the value is present).
可能包含也可能不包含非空值的容器对象。如果存在值,则 isPresent() 将返回 true 并且 get() 将返回该值。
提供了依赖于所包含值的存在与否的其他方法,例如 orElse()(如果值不存在则返回默认值)和 ifPresent()(如果该值存在则执行代码块)。
Some hints on how to use Optional
with Optional<T> findById(ID id)
.
关于如何使用Optional
with 的一些提示Optional<T> findById(ID id)
。
Generally as you look for an entity by id you want to return it or make a particular processing if that is not retrieved.
通常,当您通过 id 查找实体时,您希望返回它或在未检索到的情况下进行特定处理。
Here three classical usage examples.
这里有三个经典的用法示例。
1) Suppose that if the entity is found you want to get it otherwise you want to get a default value.
1) 假设如果找到实体,您想要获取它,否则您想要获取默认值。
You could write :
你可以写:
Foo foo = repository.findById(id)
.orElse(new Foo());
or get a null
default value if it makes sense (same behavior as before the API change) :
或者null
在有意义的情况下获取默认值(与 API 更改之前的行为相同):
Foo foo = repository.findById(id)
.orElse(null);
2) Suppose that if the entity is found you want to return it, else you want to throw an exception.
2) 假设如果找到实体你想返回它,否则你想抛出一个异常。
You could write :
你可以写:
return repository.findById(id)
.orElseThrow(() -> new EntityNotFoundException(id));
3) Suppose you want to apply a different processing according to if the entity is found or not (without necessary throwing an exception).
3)假设您想根据是否找到实体来应用不同的处理(无需抛出异常)。
You could write :
你可以写:
Optional<Foo> fooOptional = fooRepository.findById(id);
if (fooOptional.isPresent()){
Foo foo = fooOptional.get();
// processing with foo ...
}
else{
// alternative processing....
}
回答by Claudiu Guja
Indeed, in the latest version of Spring Data, findOne returns an optional. If you want to retrieve the object from the Optional, you can simply use get() on the Optional. First of all though, a repository should return the optional to a service, which then handles the case in which the optional is empty. afterwards, the service should return the object to the controller.
事实上,在最新版本的 Spring Data 中, findOne 返回一个可选的。如果要从 Optional 中检索对象,只需在 Optional 上使用 get() 即可。但是,首先,存储库应该将可选项返回给服务,然后服务处理可选项为空的情况。之后,服务应该将对象返回给控制器。
回答by Prashant
Optional
api provides methods for getting the values. You can check isPresent()
for the presence of the value and then make a call to get()
or you can make a call to get()
chained with orElse()
and provide a default value.
Optional
api 提供了获取值的方法。您可以检查isPresent()
该值是否存在,然后调用get()
或者您可以调用get()
链接orElse()
并提供默认值。
The last thing you can try doing is using @Query()
over a custom method.
您可以尝试做的最后一件事是使用@Query()
自定义方法。
回答by Oliver Drotbohm
The method has been renamed to findById(…)
returning an Optional
so that you have to handle absence yourself:
该方法已重命名为findById(…)
返回一个,Optional
以便您必须自己处理缺席:
Optional<Foo> result = repository.findById(…);
result.ifPresent(it -> …); // do something with the value if present
result.map(it -> …); // map the value if present
Foo foo = result.orElse(null); // if you want to continue just like before
回答by 147.3k
I always write a default method "findByIdOrError"in widely used CrudRepository repos/interfaces.
我总是在广泛使用的 CrudRepository 存储库/接口中编写一个默认方法“findByIdOrError”。
@Repository
public interface RequestRepository extends CrudRepository<Request, Integer> {
default Request findByIdOrError(Integer id) {
return findById(id).orElseThrow(EntityNotFoundException::new);
}
}