Java 8-类型为CrudRepository <developer,long>的save(S)方法不适用于自变量(Optional <developer>)

时间:2018-07-13 02:35:36

标签: java spring optional

我开始使用spring框架进行Java开发,并且为了使事情变得比hello世界更复杂,我找到了本教程并尝试遵循。

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

我发现的问题是,建议的代码:由于我的扩展“ CrudRepository”的类返回了Optional 和Optional 的事实,因此在DevelopersController.java内出现了Eclipse错误。而不只是一个Skill / Developer对象。

    @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";
}

但是我在日食中仍然遇到错误:

  • 列表类型中的add(Skill)方法不适用于自变量(可选)
  • 对于Optional类型,未定义方法getId()
  • CrudRepository类型的save(S)方法不适用于自变量(可选)

我该如何解决? 还为什么行:

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

未显示任何错误,但显示以下行:

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

是吗?

2 个答案:

答案 0 :(得分:1)

此行developer.get().getSkills().add(skill);是错误的。您正在尝试向类型Skill的列表中添加可选项。

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

也不要将业务逻辑放在控制器中。始终为此使用服务类。

服务类是放置业务逻辑的地方。控制器是您将业务逻辑与前端链接的地方。

答案 1 :(得分:0)

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-boot依赖低于1.6.x的spring-boot的先前版本中,您将使用:

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

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