Spring Data JPA findOne() 改为 Optional 怎么用?

新手上路,请多包涵

我正在学习 SpringBoot2.0Java8

我遵循了一些博客制作教程示例。

教程源代码为:

 @GetMapping("/{id}/edit")
public String edit(@PathVariable Long id, Model model) {
  model.addAttribute("categoryDto", categoryService.findOne(id));
  return "category/edit";
}

但是这段代码抛出了这个错误:

categoryService.findOne(id)

我正在考虑将 JPA findOne() 方法更改为 Optional< S >

如何解决?

更多信息:

这是 categoryService 方法:

 public Category findOne(Long id) {
  return categoryRepository.findOne(id);
}

原文由 Hulk Choi 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.1k
2 个回答

至少从 2.0 版本, Spring-Data-Jpa 修改 findOne()

现在, findOne() 既没有相同的签名也没有相同的行为。

之前在 CrudRepository 接口中定义为:

 T findOne(ID primaryKey);

现在,您将在 CrudRepository 中找到的单个 findOne() 方法是在 QueryByExampleExecutor 接口中定义的方法:

 <S extends T> Optional<S> findOne(Example<S> example);

最终由 SimpleJpaRepository 实现,这是 CrudRepository 接口的默认实现。

此方法是通过示例搜索进行查询,您不希望将其作为替代方法。

实际上,具有相同行为的方法仍然存在于新 API 中,只是方法名称发生了变化。

它在 CrudRepository 接口中从 findOne() 重命名为 findById()

 Optional<T> findById(ID id);

现在它返回一个 Optional ,这对于防止 NullPointerException 来说还不错。

因此,现在调用的实际方法是 Optional<T> findById(ID id)

怎么用?

学习 Optional 用法。以下是有关其规格的重要信息:

一个容器对象,可能包含也可能不包含非空值。如果存在值,isPresent() 将返回 true,而 get() 将返回该值。

提供了依赖于包含值是否存在的其他方法,例如 orElse() (如果值不存在则返回默认值)和 ifPresent() (如果值存在则执行代码块)。


关于如何使用 OptionalOptional<T> findById(ID id) 的一些提示。

通常,当您通过 id 查找实体时,如果没有检索到,您希望返回它或进行特定处理。

以下是三个经典用法示例。

  1. 假设如果找到实体,您想要获取它,否则您想要获取默认值。

你可以写:

 Foo foo = repository.findById(id)
                    .orElse(new Foo());

或获取 null 默认值(如果有意义)(与 API 更改之前的行为相同):

 Foo foo = repository.findById(id)
                    .orElse(null);

  1. 假设如果找到实体要返回它,否则要抛出异常。

你可以写:

 return repository.findById(id)
        .orElseThrow(() -> new EntityNotFoundException(id));

  1. 假设您想根据是否找到实体应用不同的处理(不一定抛出异常)。

你可以写:

 Optional<Foo> fooOptional = fooRepository.findById(id);
if (fooOptional.isPresent()) {
    Foo foo = fooOptional.get();
    // processing with foo ...
} else {
    // alternative processing....
}

原文由 davidxxx 发布,翻译遵循 CC BY-SA 4.0 许可协议

该方法已重命名为 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

原文由 Oliver Drotbohm 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题