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

软件发布|下载排行|最新软件

当前位置:首页IT学院IT技术

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

赐我白日梦   2020-01-06 我要评论

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

  • 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

Copyright 2022 版权所有 软件发布 访问手机版

声明:所有软件和文章来自软件开发商或者作者 如有异议 请与本站联系 联系我们