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

  • 相关阅读:
    错误1053:服务没有及时响应启动或控制请求
    错误号码2003 Can't connect to MySQL server 'localhost' (0)
    分析slow-log 每小时慢sql情况
    用spring annotation声明的bean,当打包在jar中时,无法被扫描到
    mysql 锁查看
    linux 使用expect
    tomcat启动报错:java.lang.ClassNotFoundException:org.springframework.web.context.ContextLoaderListener
    Spring LDAP authenticate method with Pooling
    一步步教你使用Proguard混淆Java源代码
    JAVA获取CLASSPATH路径
  • 原文地址:https://www.cnblogs.com/ZhuChangwu/p/12158405.html
Copyright © 2011-2022 走看看