【问题标题】:FetchType.Lazy not working in JPA in spring bootFetchType.Lazy 在 Spring Boot 中无法在 JPA 中工作
【发布时间】:2020-10-27 23:47:59
【问题描述】:

我有一个实体 Order.java 作为:

package in.ashwin.onlinebookstore.entity;

import java.util.Date;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;

@Entity
@Table(name="tbl_order")
public class Order {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long order_id;
    
    @OneToOne(cascade = CascadeType.MERGE,fetch = FetchType.LAZY)
    @JoinColumn(name = "user_id", nullable = false)
    private User user;
    
    @Column(name="today_date")
    private Date todayDate;
    
    @Column(name="status")
    private String status;
    
    public Order(User user, Date todayDate) {
        
        this.user = user;
        this.todayDate = todayDate;
        this.status="pending";
    }

    public Long getOrder_id() {
        return order_id;
    }

    public void setOrder_id(Long order_id) {
        this.order_id = order_id;
    }

    public String getStatus() {
        return status;
    }

    

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public Date getTodayDate() {
        return todayDate;
    }

    public void setTodayDate(Date todayDate) {
        this.todayDate = todayDate;
    }
    
    public Order() {
        
    }

}

我在用户和订单之间包含了 Fetchtype 作为惰性。因为,我在获取订单时声明了 FetchType.LAZY,当我从邮递员测试时,我仍然看到用户对象被调用。根据我的理解,FetchType 的对象。 LAZY 只在需要时才被调用。如果没有调用,则忽略它。

 @OneToOne(cascade = CascadeType.MERGE,fetch = FetchType.LAZY)
        @JoinColumn(name = "user_id", nullable = false)
        private User user;

我获取所有订单的 api 是:

@GetMapping("/getAllPendingOrders")
    @PreAuthorize("hasRole('USER') or hasRole('MODERATOR') or hasRole('ADMIN')")
    public ResponseEntity<?> getOrders(Pageable pageable) {
        
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        String user = auth.getName();
        UserDetailsImpl userDetails=(UserDetailsImpl)userdetailService.loadUserByUsername(user);
        
        Page<Order> orderList=orderRep.findByUserId(userDetails.getId(),pageable);
        if(orderList!=null) {
             return new ResponseEntity(orderList, HttpStatus.OK);
        }
        else {
             return new ResponseEntity("Noorders", HttpStatus.OK);
        }
       
        
    }

我从 POSTMAN 收到的回复是:

{
    "content": [
        {
            "order_id": 1,
            "user": {
                "id": 1,
                "username": "ashwin",
                "email": "ashwin@gmail.com",
                "password": "$2a$10$GoGUJh0Tzml5egBW5Wzbj.VLzfq4Z7YNCMnsOynLWufpQrWBdVLVi",
                "roles": [
                    {
                        "id": 2,
                        "name": "ROLE_MODERATOR"
                    },
                    {
                        "id": 1,
                        "name": "ROLE_USER"
                    }
                ]
            },
            "todayDate": "2020-07-02T17:09:45.057+0000",
            "status": "pending"
        },
        {
            "order_id": 2,
            "user": {
                "id": 1,
                "username": "ashwin",
                "email": "ashwin@gmail.com",
                "password": "$2a$10$GoGUJh0Tzml5egBW5Wzbj.VLzfq4Z7YNCMnsOynLWufpQrWBdVLVi",
                "roles": [
                    {
                        "id": 2,
                        "name": "ROLE_MODERATOR"
                    },
                    {
                        "id": 1,
                        "name": "ROLE_USER"
                    }
                ]
            },
            "todayDate": "2020-07-02T17:15:06.906+0000",
            "status": "pending"
        },
        {
            "order_id": 3,
            "user": {
                "id": 1,
                "username": "ashwin",
                "email": "ashwin@gmail.com",
                "password": "$2a$10$GoGUJh0Tzml5egBW5Wzbj.VLzfq4Z7YNCMnsOynLWufpQrWBdVLVi",
                "roles": [
                    {
                        "id": 2,
                        "name": "ROLE_MODERATOR"
                    },
                    {
                        "id": 1,
                        "name": "ROLE_USER"
                    }
                ]
            },
            "todayDate": "2020-07-02T17:16:36.373+0000",
            "status": "pending"
        },
        {
            "order_id": 4,
            "user": {
                "id": 1,
                "username": "ashwin",
                "email": "ashwin@gmail.com",
                "password": "$2a$10$GoGUJh0Tzml5egBW5Wzbj.VLzfq4Z7YNCMnsOynLWufpQrWBdVLVi",
                "roles": [
                    {
                        "id": 2,
                        "name": "ROLE_MODERATOR"
                    },
                    {
                        "id": 1,
                        "name": "ROLE_USER"
                    }
                ]
            },
            "todayDate": "2020-07-02T17:18:56.799+0000",
            "status": "pending"
        }
       
    ],
    "pageable": {
        "sort": {
            "sorted": false,
            "unsorted": true,
            "empty": true
        },
        "offset": 0,
        "pageNumber": 0,
        "pageSize": 20,
        "paged": true,
        "unpaged": false
    },
    "totalPages": 2,
    "last": false,
    "totalElements": 39,
    "size": 20,
    "number": 0,
    "sort": {
        "sorted": false,
        "unsorted": true,
        "empty": true
    },
    "numberOfElements": 20,
    "first": true,
    "empty": false
}

我仍然在我的 JSON.USing 中看到用户对象,@JSONIgnore 有效,但是由于我已将其声明为 Fetchtype.Lazy,为什么当我获取 Order 对象时会出现 USER 对象?我不知道当我获取 Order 对象时,希望 User 对象出现。

【问题讨论】:

  • Fetchtype.Lazy 只是表示,每当你调用一个订单时,用户不会同时来,只是在需要的时候,会再次查询数据库来获取这个信息。在这种情况下,您有您的存储库,这将调用所有的订单信息,因为它是创建 JSON 所必需的。
  • 那么,这意味着存储库忽略了 FetchType.Laay?

标签: java spring-boot hibernate jpa


【解决方案1】:

User 实体数据在显式调用之前不会被初始化并加载到内存中。您的 Order 实体包含 user 字段。因此,当序列化用户调用的订单数据获取器和使用另一个查询获取的用户数据时。

如果您不想使用@JsonIgnore,请为没有用户字段的订单创建响应类并映射您的数据。

【讨论】:

  • 所以,假设如果我删除用户的 getter 并仍然放置 Fetchtype.lazy,那么如果我需要 order.getUser(),我该如何访问。如何访问用户对象?虽然可能有 getter,但如果我们声明 Fetchtype.Lazy 那么它会省略用户对象是吗?
【解决方案2】:

对我来说添加 @JsonIgnore 注释有帮助

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2015-04-20
  • 2018-11-07
  • 1970-01-01
  • 2020-05-04
  • 2018-06-01
  • 2018-06-07
  • 2016-10-04
  • 2019-08-04
相关资源
最近更新 更多