zoukankan      html  css  js  c++  java
  • 记: 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

  • 相关阅读:
    二叉树知识拓展
    【2014年鄞州区】小幸福(e.pas/c/cpp)
    【2017年常州市】小X与队列 (queue)
    【2018年南海区甲组】扑克游戏(poker)
    【2018年南海区甲组】拆除桥墩(remove)
    【NOIP普及组模拟赛3】投影(skyline)
    常用正则表达式
    asp.net访问母版页控件方法
    C#文件读写操作
    C#读取csv格式文件
  • 原文地址:https://www.cnblogs.com/ZhuChangwu/p/12158405.html
Copyright © 2011-2022 走看看