【问题标题】:Java 8 - The method save(S) in the type CrudRepository<Developer,Long> is not applicable for the arguments (Optional<Developer>)Java 8 - CrudRepository<Developer,Long> 类型中的方法 save(S) 不适用于参数(可选<Developer>)
【发布时间】:2018-07-13 02:35:36
【问题描述】:

我开始使用 spring 框架进行 java 开发,为了获得比 hello world 更复杂的东西,我找到了本教程并尝试遵循。

https://www.toptal.com/spring/beginners-guide-to-mvc-with-spring-framework

我发现的问题是,建议的代码:由于我的扩展“CrudRepository”的类返回一个可选 和 Optional ,因此在 DevelopersController.java 内部在 eclipse 中出现错误而不仅仅是一个技能/开发者对象。

    @RequestMapping(value="/developer/{id}/skills", method=RequestMethod.POST)
    public String developersAddSkill(@PathVariable Long id, @RequestParam Long skillId, Model model) {
    Skill skill = skillRepository.findOne(skillId);
    Developer developer = repository.findOne(id);

    if (developer != null) {
        if (!developer.hasSkill(skill)) {
            developer.getSkills().add(skill);
        }
        repository.save(developer);
        model.addAttribute("developer", repository.findOne(id));
        model.addAttribute("skills", skillRepository.findAll());
        return "redirect:/developer/" + developer.getId();
    }

    model.addAttribute("developers", repository.findAll());
    return "redirect:/developers";
}

我查找了有关 Java 8 Optional 的一些信息,但由于我仍然缺乏编码经验,我很难理解如何正确使用它。

我将代码更改为并设法解决了其中一个错误......

    @RequestMapping(value="/developer/{id}/skills", method=RequestMethod.POST)
    public String developersAddSkill(
        @PathVariable Long id, 
        @RequestParam Long skillId, 
        Model model) {
    Optional<Skill> skill = skillRepository.findById(skillId);
    Optional<Developer> developer = repository.findById(id);

    developer.get().getSkills();
    if (developer != null) {
        if (!developer.get().hasSkill(skill)) {
            developer.get().getSkills().add(skill);
        }
        repository.save(developer);
        model.addAttribute("developer", repository.findById(id));
        model.addAttribute("skills", skillRepository.findAll());
        return "redirect:/developer/" + developer.getId();
    }
    return "Confused";
}

但我的 Eclipse 中仍然出现以下错误:

  • 类型 List 中的方法 add(Skill) 不适用于参数(可选)
  • 方法 getId() 未为 Optional 类型定义
  • CrudRepository 类型中的方法 save(S) 不适用于参数(可选)

我该如何解决这个问题? 还有为什么行:

if (!developer.get().hasSkill(skill)) {

显示没有错误,但行:

developer.get().getSkills().add(skill);

会吗?

【问题讨论】:

  • 你为什么不试试这样:可选 optionalDeveloper = repository.findById(id);开发者 developer = optionalDeveloper.get(); if (developer != null) { if (!developer.hasSkill(skill)) { developer.getSkills().add(skill); } repository.save(开发者); model.addAttribute("开发者", repository.findOne(id)); model.addAttribute("技能", SkillRepository.findAll());返回“重定向:/developer/” + developer.getId(); }

标签: java spring optional


【解决方案1】:

changelog 中所述,较新版本的 spring-data(1.6.0 以上)将为 findById() 方法返回 Optional。在以前版本的 spring-data 中,如果在数据库中找不到具有指定 id 的对象, findById() 的结果将是 null

如您的示例所示,Optional 可能包含一些开发人员或没有开发人员。要检查 findById() 是否返回了您应该使用的开发人员:

//You probably should rename the developer variable to "result".
Optional<Developer> developer = repository.findById(id);
if(developer.isPresent()){
    //developer found, you can get it.
    Developer aDeveloper = developer.get();
    //aDeveloper.hasSkill(skill); is acessible now.
}else{
    //no developer found with the specified Id.
}

在 spring-data 依赖低于 1.6.x 的以前版本的 spring-boot 中,您将使用:

Developer developer = repository.findById(id);
if (developer != null) {
    //developer found       
}

如果在没有开发人员的情况下尝试 developer.get(),则会抛出异常。因此,请先检查 isPresent()。

【讨论】:

  • 对于 Java 9,通常最好使用 isPresentOrElse 而不是使用 if 语句。
【解决方案2】:

这行developer.get().getSkills().add(skill); 是错误的。您正在尝试将 Optional 添加到 Skill 类型的列表中。

要修复此错误,您必须将其更改为 developer.get().getSkills().add(skill.get());

另外,永远不要将业务逻辑放在控制器中。始终为此使用服务类。

服务类是您放置业务逻辑的地方。控制器是将业务逻辑与前端联系起来的地方。

【讨论】:

  • 现在我设法理解了答案,谢谢你当你说我应该为我的业务逻辑使用服务类时,你有什么建议在这种情况下我该怎么做?跨度>
  • 遵循 MVC 模式。 Spring MVC 完全支持这一点。你的每一层都有责任,除了他们的责任,不应该做任何事情。控制器应该链接 UI 和业务逻辑。服务类执行业务逻辑(放置 if 和 else 条件的地方)。存储库应该用来保存您的域对象。因此,创建一个单独的类并将 addDevelopersSkills 中的逻辑移动到该类(或与开发人员相关的任何其他逻辑)。您可以找到相关的注解,例如 Controller、Service、Repository。
猜你喜欢
  • 1970-01-01
  • 2019-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-17
  • 1970-01-01
  • 2014-06-26
相关资源
最近更新 更多