关于java:Hibernate:为什么FetchType.LAZY-annotated集合属性急切加载?

Hibernate : Why FetchType.LAZY-annotated collection property eagerly loading?

我试图实现简单的一对多的关联。在使用调试模式检查项目对象之后,我发现已经加载了listbids。但是listbids属性用fetchtype.lazy注释。一些书籍和网页声称fetchtype.lazy是JPA提供者接受或拒绝的提示。但我想知道JPA提供者忽略fetchtype.lazy的条件是什么。提前谢谢。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
@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 +
                '}';
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
@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 +
                '}';
    }
}

1
2
3
4
5
6
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


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

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


作为休眠文档@OneTomany--默认fetchType为lazy@manytoone——默认fetchtype是热切的。

如果要更改,则fetch=fetchtype.lazy/earger

基本上,Hibernate对象有两次1)实体对象2)值对象。因此在您的情况下,项目与BID有一对多关系,如果您在那时检索到项目类,Hibernate将不会获取相关的BID类记录,因为您确实提取了类型为lazy,但您提取了BID类记录。Hibernate急切地为您获取相关的项,因为bid与item类有一个manytoone关系,manytoone的默认获取类型是热切的。