休眠 :为什么 FetchType.LAZY 注释的集合属性急切地加载?

2022-09-02 09:47:49

我试图实现简单的关联。使用调试模式检查项对象后,我发现已经加载。但是 bids 属性用 注释。一些书籍和网页声称这是JPA提供者接受或拒绝的提示。但是我想知道JPA提供者在什么条件下忽略.提前感谢您。one-to-manyList<Bid> bidsList<Bid>FetchType.LAZYFetchType.LAZYFetchType.LAZY

@Entity
@Table(name = "ITEM")
public class Item implements Serializable {

    @Id
    private Long id = null;

    private String name;
    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "SELLER_ID", nullable = false)
    private User seller;

    @OneToMany(mappedBy = "item", fetch = FetchType.LAZY)
    private List<Bid> bids;

    /**
     * No-arg constructor for JavaBean tools.
     */
    public Item() {}

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public User getSeller() {
        return seller;
    }

    public void setSeller(User seller) {
        this.seller = seller;
    }

    @Override
    public String toString() {
        return "Item{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", seller=" + seller +
                ", bids=" + bids +
                '}';
    }
}
@Entity
@Table(name = "BID")
public class Bid implements Serializable {

    @Id @GeneratedValue
    @Column(name = "BID_ID")
    private Long id = null;

    @ManyToOne
    @JoinColumn(name = "ITEM_ID", nullable = false, updatable = false, insertable = false)
    private Item item;

    @ManyToOne
    @JoinColumn(name = "BIDDER_ID", nullable = false, updatable = false)
    private User bidder;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Item getItem() {
        return item;
    }

    public void setItem(Item item) {
        this.item = item;
    }

    public User getBidder() {
        return bidder;
    }

    public void setBidder(User bidder) {
        this.bidder = bidder;
    }

    @Override
    public String toString() {
        return "Bid{" +
                "id=" + id +
                ", bidder=" + bidder +
                '}';
    }
}
private static void itemSeller(EntityManager em) {

    Item item = em.find(Item.class, 1L);
    System.out.println("hello");

}

编辑:我把断点放在语句上。我检查了项目对象。见图片:System.out.println("hello")enter image description here


答案 1

通过在调试器中检查对象,您可以要求它调用列表的方法以显示其大小、内容等。这当然会懒惰地初始化列表。

您的方法也是如此,它隐式循环遍历列表以打印它。toString()


答案 2

由于Hibernate文档@OneToMany - 默认fetchType是LAZY @ManyToOne - 默认fetchType是EAGER。

如果你想改变,那么 fetch=fetchType.LAZY/EAGER

基本上,有两次休眠对象 1)实体对象 2)有价值的 Object.So 在你的情况下 项目与 Bid 有对数关系,如果你检索 Item 类在那个时候休眠不会获取相关的 Bid 类记录,因为你确实获取类型是 LAZY,但是你获取 Bid 类记录休眠获取相关项目为你热切地, 因为 Bid 与 Item 类有 ManyToOne 关系,而 ManyToOne 的默认抓取类型是 EAGER。


推荐