记: Spring Data Jpa @OneToMany 级联查询被动触发的问题
赐我白日梦 人气:5I have encountered a bug in using Spring Data Jpa. Specifically,when @OneToMany was used to maintain a one-to-many relationship, lazy loading was effective.However,it may passively trigger the cascading query without using the cascading property.
My development environment :
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.11.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
My User.class is as follows
My Paper.class is as follows
My PaperService.class is as follows
My UserController.class is as follows
I would like to use Jpa's @OneToMany default lazy loading mechanism when pagination queries was produced. Additionally, I don't need the collection of papers fields associated with the user.Nevertheless,I find that the papers attribute in the user is still populated with data in the returned results.
Therefore, I conducted the following debugging:**
send a request
Observe the execution of the code:
As you can see, although the lazy loading of Jpa was normal, I found the papers values that needed to be populated by cascading queries in the response data
I guess the user's papers field in Page must have been used by the framework before the data was written back to the browser, so I started with the UserController and continued to trace the source code
Then I was found the following call: Jackson called paper's getter through reflection while serializing the data . in the package com. Fasterxml. Jackson. Databind. Ser.
That's why I get a response in which the paper property is populated with a value, right
Look at it this way, even though lazy loading of Jpa is in effect, cascading queries are triggered passively
Lazy loading is in effect, but the cascading query is still triggered passively, which is not the result we want, I wonder what you think about it
- solution 1:
@RequestMapping(path = "/getUserByPage")
public Page getUserByPage(@RequestParam Integer from, @RequestParam Integer limit, @RequestParam(required = false) String name) {
Page<User> page = userService.getUserByPage(from, limit, name);
page.getContent().forEach(user->{
user.setPapers(null);
});
return page;
}
- solution 2:
@JsonIgnore
@JsonIgnore
can handle this pretty well, so why not let @onetomany have it?
@JsonIgnore
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL,fetch = FetchType.LAZY)
private Set<Paper> papers = new HashSet<>();
- solution 3:
We can get rid of the getters (papers), but if we do that, we can't use the property by ourselves
加载全部内容