Hibernate:为啥 FetchType.LAZY 注释的集合属性急切地加载?
Posted
技术标签:
【中文标题】Hibernate:为啥 FetchType.LAZY 注释的集合属性急切地加载?【英文标题】: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() 方法也是如此,它会隐式循环遍历列表以打印它。 【参考方案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。
【讨论】:
以上是关于Hibernate:为啥 FetchType.LAZY 注释的集合属性急切地加载?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 Spring 在使用 Hibernate 3 时推迟关闭 Hibernate 会话
为啥 hibernate 严格要求定义 hibernate.dialect 属性,而 JPA 规范没有强制要求?
为啥 Hibernate 会为此 HQL 抛出 QuerySyntaxException?