Jackson仍然返回延迟获取字段的Json值。

huangapple go评论65阅读模式
英文:

Jackson still return Json value of lazy fetched field

问题

public class Student {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "status_id")
    private StudentStatus statusID;

This is the controller:

public Page<StudentDTO> getAllStudents(@RequestParam(defaultValue = "0") int page,
                                      @RequestParam(defaultValue = "10") int size,
                                      @RequestParam(name = "filter", required = false) String fieldName,
                                      @RequestParam(name = "value", required = false) String fieldValue) {
    Pageable pageable = PageRequest.of(page, size);
    Specification<Student> spec = StudentSpecification.hasFieldWithValueLike(fieldName, fieldValue);
    return studentService.getStudents(spec, pageable);
}

Service:

public Page<StudentDTO> getStudents(Specification<Student> spec, Pageable pageable) {
    Page<Student> studentPage = studentRepository.findAll(spec, pageable);
    return studentPage.map(student -> studentMapper.toDTO(student));
}

I know that my lazy fetch is successful because it returns an extra field: hibernateLazyInitializer.

From my understanding, the returned JSON from a GET will not have any data for the lazy fetched field StudentStatus, but the response still has all the value of StudentStatus.

I also benchmark my API using JMeter for 10000 requests. And it seems like without lazy fetch it's actually faster by 2ms on average.


<details>
<summary>英文:</summary>

I have a `Student` class with a `OnetoOne` relationship.
```java
public class Student {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @OneToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = &quot;status_id&quot;)
    private StudentStatus statusID;

This is the controller:

public Page&lt;StudentDTO&gt; getAllStudents(@RequestParam(defaultValue = &quot;0&quot;) int page,
                             @RequestParam(defaultValue = &quot;10&quot;) int size,
                             @RequestParam(name = &quot;filter&quot;, required = false) String fieldName,
                             @RequestParam(name = &quot;value&quot;, required = false) String fieldValue) {
        Pageable pageable = PageRequest.of(page, size);
        Specification&lt;Student&gt; spec = StudentSpecification.hasFieldWithValueLike(fieldName,fieldValue);
        return studentService.getStudents(spec, pageable);}

Service:

public Page&lt;StudentDTO&gt; getStudents(Specification&lt;Student&gt; spec, Pageable pageable) {
    Page&lt;Student&gt; studentPage = studentRepository.findAll(spec, pageable);
    return studentPage.map(student -&gt; studentMapper.toDTO(student));}

I know that my lazy fetch is successful because it returns an extra field: hibernateLazyInitializer.

From my understanding, the returned json from a GET will not have any data for the lazy fetched field StudentStatus, but the response still has all the value of StudentStatus.

I also benchmark my API using JMeter for 10000 requests. And it seems like without lazy fetch it's actually faster by 2ms on average.

答案1

得分: 1

这就是 Hibernate 惰性加载的工作方式。StudentStatus 不会在 findAll 方法中获取。它只会被替代为代理。然而,在下一行中,您的映射器访问了 statusID 字段的 getter,导致 Hibernate 使用额外的 select 语句获取 StudentStatus 实体。这当然会花费一些额外的时间。

如果您不需要在您的 StudentDTO 中包含 StudentStatus,您可以从映射器中将其移除。

英文:

This is exactly how Hibernate lazy loading works. The StudentStatus will not be fetched with the findAll method. It will be only substituted with a proxy. However in the next line your mapper access the getters of the statusID field causing Hibernate to fetch the StudentStatus entity with an additional select statement. This will of course take some additional time.

If you don't need the StudentStatus in your StudentDTO you can remove it from the mapper.

huangapple
  • 本文由 发表于 2023年6月15日 14:20:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/76479634.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定