从JpaRepository的方法findAll返回的类实体在构造函数内部计算的字段上具有null字段值

enyaitl3  于 2023-05-23  发布在  其他
关注(0)|答案(1)|浏览(120)

我有一个Student类,它有一些字段,包括“age”和“dateOfBirth”。age值在构造函数中根据dateOfBirth计算并属性化,如下所示:

//Student.java

private Integer id;
private String name;
private String email;
private LocalDate dateOfBirth;
@Transient
private Integer age;

public Student(String name, String email, LocalDate dateOfBirth) {
    this.name = name; // ex: "John Doe"
    this.email = email; // ex: "johndoe@gmail.com"
    this.dateOfBirth = dateOfBirth; // ex: LocalDate.of(2002, Month.MAY, 1));
    this.age = Period.between(dateOfBirth, LocalDate.now()).getYears(); // result: 21
}

Student类中的getAge()方法返回age字段值

//Student.java

public Integer getAge() {
    return age; // Returns the expected value (21)
}
  • (每隔一个字段的getter与getAge()的结构相同:返回字段的值)*

我也有一个简单的仓库,从DB查询数据。它从JpaRepository延伸出来,里面什么都没有:

//StudentRepository.java

@Repository
public interface StudentRepository extends JpaRepository<Student, Integer> { }

在StudentController类中,我有一个到"/"的路由,它只是从DB获取所有学生并返回他们:

//StudentController.java

@GetMapping("/")
public List<Student> getStudents() {
     return studentService.getStudents();
}

我期望的结果如下,年龄字段的值为21:

[{"id":1,"name":"John Doe","email":"johndoe@gmail.com","dateOfBirth":"2002-05-01","age":21}]

相反,我得到了一个年龄字段的null值:

[{"id":1,"name":"John Doe","email":"johndoe@gmail.com","dateOfBirth":"2002-05-01","age":null}]

但是如果我将Student类的getAge()方法实现更改为:

// Student.java

 public Integer getAge() {
    return Period.between(dateOfBirth, LocalDate.now()).getYears();
}

我得到的是21,而不是null

[{"id":1,"name":"John Doe","email":"johndoe@gmail.com","dateOfBirth":"2002-05-01","age":21}]
46scxncf

46scxncf1#

JPA不使用构造函数。JPA规范要求无参数构造函数。如果您没有提供一个无参数构造函数,您的JPA实现可以为您创建一个(例如openjpa就提供了,请参阅https://openjpa.apache.org/builds/1.2.3/apache-openjpa/docs/jpa_overview_pc.html#jpa_overview_pc_no_arg)。
这就是为什么当您更改getter以计算年龄值时,您的代码可以正常工作。
如果你不想在每次调用getter时都重新计算年龄,你可以:

  • 在setDateOfBirth()方法中设置出生日期时计算年龄。
  • 在getAge()方法中延迟计算并存储年龄。类似于:
public Integer getAge() {
      if (age == null && dateOfBirth != null) {
        age = Period.between(dateOfBirth, LocalDate.now()).getYears();
       }
       return age;
    }

相关问题