【问题标题】:Hibernate : Why FetchType.LAZY-annotated collection property eagerly loading?Hibernate:为什么 FetchType.LAZY 注释的集合属性急切地加载?
【发布时间】:2017-03-19 03:56:05
【问题描述】:

我尝试实现简单的one-to-many 关联。在使用调试模式检查项目对象后,我发现 List<Bid> bids 已经加载。但是List<Bid>bids 属性用FetchType.LAZY 注释。一些书籍和网页声称FetchType.LAZY 是 JPA 提供者接受或拒绝的暗示。但我想知道 JPA 提供商在什么情况下会忽略 FetchType.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") 处设置了断点。我检查了项目对象。看图片:

【问题讨论】:

  • 你如何确定它是热切加载的?你的测试是什么?
  • 1-N 的默认值为 LAZY,因此指定它是没有意义的。提供者所做的是特定于您的 JPA 提供者(没有“声称”它只是一个提示......在 JPA 规范中)。我使用的提供者 (DataNucleus) 始终尊重我告诉它使用的内容。你的可能认为它比你更了解?它比你更了解吗?
  • @NeilStockton Hibernate 当然支持延迟加载。是的,JPA 规范确实这么说:docs.oracle.com/javaee/7/api/javax/persistence/….
  • 通过检查调试器中的对象,您要求它调用列表的方法以显示其大小、内容等。这当然会懒惰地初始化列表。您的 toString() 方法也是如此,它会隐式循环遍历列表以打印它。

标签: java hibernate jpa


【解决方案1】:

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

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

【讨论】:

  • 看到你的回答后,我觉得我的问题很愚蠢。我考虑过删除这篇文章,因为我太丢脸了。现在我对投票的数量感到惊讶,我很高兴即使是我的愚蠢问题也能对其他人派上用场。再次感谢您的回答。
  • @inherithandle 没有必要为只有在我们尝试时才会学习而感到羞耻,我在谷歌上输入了同样的担忧并登陆您的线程,看看一个问题如何帮助其他人。感谢询问
【解决方案2】:

作为 Hibernate 文档 @OneToMany--默认 fetchType 是 LAZY @ManyToOne--默认 fetchType 是 EAGER。

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

基本上,休眠对象有两次1)实体对象2)值对象。所以在你的情况下,项目与投标有一对多的关系,如果你当时检索项目类,休眠将不会获取相关的投标类记录,因为您确实获取类型是 LAZY,但是您获取 Bid Class 记录休眠为您急切获取相关项目,因为 Bid 与 Item 类具有 ManyToOne 关系,并且 ManyToOne 的默认获取类型是 EAGER。

【讨论】:

    猜你喜欢
    • 2013-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-14
    相关资源
    最近更新 更多