英文:
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 = "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.
答案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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论