有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java变量id可能未使用lombok初始化Spring引导控制器

我试图添加一个简单的控制器方法,但遇到以下问题 Exercise.java:[13,1] variable id might not have been initialized

这是我正在使用的代码

@RequestMapping(value = "/exercises/{id}")
    public ResponseEntity<Optional<Exercise>> getExerciseById(Model model, @PathVariable Integer id) {
        Optional<Exercise> exercise = exerciseRepository.findById(id);
        if(id!=null)
            return new ResponseEntity<Optional<Exercise>>(exercise, HttpStatus.OK);
        else
            return new ResponseEntity<Optional<Exercise>>(exercise, HttpStatus.NOT_FOUND);
    }

我在这里使用Optional<Exercise>,因为我利用了JpaRepository包中的内置方法findById。我还没有找到任何关于如何处理这个问题的好帖子。这可能很简单。我已经找到了一些关于这方面的文档:https://www.java67.com/2016/07/how-to-fix-variable-might-not-have-been-initialized-error-in-java.html,但是我需要一些帮助来理解解决这个问题的最佳方法。这是练习课

@Entity
@Table(name = "exercise")
@Value
@NoArgsConstructor
public class Exercise {
    
    @Id
    @NonNull
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;

    private int chapterId;

    private String exercise;

    private String answer;

    private String question;

    private String a;
    
    private String b;

    private String c;
}

共 (1) 个答案

  1. # 1 楼答案

    tldr

    我认为JPA不能很好地处理@Value创建的不变实体。改用@Data

    ihnbtdttrt(我没有什么比读这篇文章更好的事要做)

    这部分是猜测,但由于它似乎有所帮助,这就是我认为正在发生的事情:

    当调用findById()时,JPA使用无参数构造函数创建一个新的实体对象,然后分别设置字段。(我不确定它是使用setter还是直接使用反射设置字段)

    如文档所示,@Value注释here使类不可变,所有字段都是私有的和最终的,并且没有创建“setter”。这意味着设置字段的唯一方法是将字段值传递给具有适当参数的构造函数。在那之后,这些领域是不可改变的

    由于JPA使用无参数构造函数初始化实体,并在之后尝试设置字段,因此在您的设置中,它使用无参数构造函数,并最终生成一个实体对象,其中没有任何字段已初始化,但在构造函数之后,没有任何字段可修改。所有私有、最终字段,没有设置符。然后它尝试调用entity.getId(),而id字段尚未初始化,导致上述错误

    要解决这个问题,可以使用@Data{a2}而不是@Value。这与此类似,但不会创建不变的对象。特别是,它生成“setter”函数,并且字段未设置为final。这是JPA所期望的Java bean类型,可以用无参数构造函数初始化,然后设置字段

    可能有一些方法可以配置JPA以不同的方式创建对象,以便它将所有数据传递到构造函数中,这样您就可以拥有不可变的实体。我知道有些Spring DI的东西是可以配置的,可以使用像这样的丰富构造函数进行初始化,但是Idk对JPA是有兴趣的

    值得一提的是,我欣赏不可变对象对于干净代码的价值,但在使用流行的Java框架(如JPA/Hibernate、Spring等)时,发现上面的无arg构造+后期构造设置模式并不少见。它们并不总是能很好地处理不可变性