问题 Hibernate延迟加载不起作用


我使用的是版本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加载父进程?


5670
2018-03-03 12:09


起源



答案:


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

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


8
2018-03-03 12:15



感谢您的解释。我现在明白了 - Farouk Alhassan


答案:


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

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


8
2018-03-03 12:15



感谢您的解释。我现在明白了 - Farouk Alhassan


父配置 正确地 至 懒散地加载 ,重点是你 错误地测试它

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

你可以通过配置来检查这个东西 show_sql 为真。它会在您调用时调用查询 getParent()


7
2018-03-03 12:13





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

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


1
2018-06-20 19:36





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

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。请谨慎使用此快捷方式,我建议您在使用此解决方案之前考虑其他方法。


0
2018-03-03 12:42





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

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

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


0
2018-03-03 12:42