记: Spring Data Jpa @OneToMany 级联查询被动触发的问题

时间:2020-01-06 22:38:32   收藏:0   阅读:420

I 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

    @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;
    }

@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<>();

We can get rid of the getters (papers), but if we do that, we can‘t use the property by ourselves

原文:https://www.cnblogs.com/ZhuChangwu/p/12158405.html

评论(0
© 2014 bubuko.com 版权所有 - 联系我们:wmxa8@hotmail.com
打开技术之扣,分享程序人生!