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

  • 相关阅读:
    欠拟合与过拟合概念和局部加权回归
    ActionEvent之TextField
    事件模型的介绍与Button的ActionListener
    布局管理器
    GUI初步和frame&panel
    生产者消费者问题
    线程同步
    [BZOJ 1407] Savage
    [BZOJ 1145] 图腾totem
    [BZOJ 1150] 数据备份
  • 原文地址:https://www.cnblogs.com/ZhuChangwu/p/12158405.html
Copyright © 2011-2022 走看看