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


    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 **

    user

    **My Paper.class is as follows **

    Paper

    My PaperService.class is as follows

    PaperService

    My UserController.class is as follows

    Controller

    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

    调试1

    Observe the execution of the code:

    调试2

    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

    调试3

    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.

    调试5

    **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 **

    调试6

    **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

  • 相关阅读:
    问题:在手动刷新aspx页面时,出现“不重新发送信息,则无法刷新网页。请单击“重试”,或单击“取消”返回正查看的页。”
    asp.net Listbox实现双向加入、删除
    C#中String对象转换为Font对象的方法
    VS2010中水晶报表应用及实例
    asp.net TreeView中checkBox的单选
    sql server 2005 A字段相同数据的B字段合并
    asp.net 显示柱状图 饼状图
    C#多态
    Css层叠样式
    C#委托
  • 原文地址:https://www.cnblogs.com/ZhuChangwu/p/12158405.html
Copyright © 2020-2023  润新知