Hibernate延迟加载无法正常工作

时间:2011-03-03 12:09:38

标签: java hibernate jpa jpa-2.0

我正在使用版本3.6.1.Final

我的实体bean中有以下属性

    @JoinColumn( name = "FOLDER_PARENT_ID", referencedColumnName = "FOLDER_ID" )
@ManyToOne(cascade=CascadeType.MERGE, fetch= FetchType.LAZY )
private FolderTbl parent;

在我的单元测试中,Assertnull失败,因为getParent()不为null

assertNull( folderTbl.getParent() );

我还需要做些什么来阻止hibernate加载父级?

5 个答案:

答案 0 :(得分:8)

即使将lazy设置为true,父值也不会为null。延迟加载使用代理对象并将其分配给父属性。当我们尝试使用父(call getParent())时,它将使用代理对象加载实际的父对象。

如果您不想加载该对象,请不要为该项配置JPA属性并将其设置为瞬态。

答案 1 :(得分:7)

父配置正确 懒惰加载,重点是错误地测试

Hibernate将在您调用方法getParent()时加载对象,当对实际对象的请求到来时,它将加载。

您可以通过将show_sql配置为true来检查此事。它会在您调用getParent()

时调用查询

答案 2 :(得分:1)

Hibernate将Lazy抓取视为提示。以下是JPA 2.0规范在第364页表9中所述的内容。

  

(可选)是字段值还是属性值   应该懒散地加载或必须急切地取出。该   EAGER策略是持久性提供程序的要求   运行时必须急切地获取该值。该   LAZY策略是对持久性提供程序运行时的暗示。

答案 3 :(得分:0)

对于某些情况,您可能根本不需要加载延迟集合。您可以使用下面的方法从会话中分离集合。

public class. .... {
.....
  @JoinColumn( name = "FOLDER_PARENT_ID", referencedColumnName = "FOLDER_ID" )
  @ManyToOne(cascade=CascadeType.MERGE, fetch= FetchType.LAZY )
  private FolderTbl parent;
  ...
  public void detachLazyObjects() {
     parent = null;
  }

然后调用此方法将类从您需要的位置分离为null。请谨慎使用此快捷方式,我建议您在使用此解决方案之前考虑其他方法。

答案 4 :(得分:0)

实际上,调用getParent()可能会返回一个代理实例,显示有父代。 如果您访问id以外的字段,则必要时将加载父项。

请注意,父级可能已由事务加载,因此驻留在第一级缓存中。如果是这样,Hibernate通常不会对数据库进行另一次查询。

如前所述,如果您的实体具有对父级的非瞬态引用,则getParent()将始终返回非null值,即使父级本身尚未加载。