动态渴望&在Hibernate中加载延迟

时间:2016-01-26 05:04:04

标签: java hibernate orm lazy-evaluation eager

我是Hibernate的新手,但对C#中的Entity Framework有丰富的经验。我喜欢的一个功能是能够动态决定在查询中立即加载的内容。例如,考虑类和学生实体的一对多关系。

在“查看课程”页面上,我可以这样做:

context.Configuration.EnableLazyLoading = true; //default option
List<Classes> classes = context.Classes.ToList();

现在我可以愉快地展示课程信息,而不会浪费资源收集学生数据。仅当用户单击“使用Rosters查看类”时,我才会执行以下操作:

context.Configuration.EnableLazyLoading = true;
List<Classes> classes = context.Classes.Include(c => c.Students).ToList();

通过这一个陈述,我能够决定在这种特殊情况下,我想立即获取所有信息。不是两个查询。不是一百个查询。只需一个查询。尽管在几秒钟之前只加载了类。

我对Hibernate的所有阅读都解释了如何在关系的配置文件中指定lazy =“true | false”,但我真的想要决定何时动态加载集合。毕竟,我对买一辆只有30英里每小时或60英里每小时的汽车不感兴趣。我需要根据我的位置选择速度。

也许使用获取模式作为JOIN的选项是可以接受的,因为在这种情况下它只会是两个查询(一个用于课程,一个用于学生),但我真的很喜欢可以选择在一个查询,特别是如果我要加载多个子集合并且不希望每个关系执行查询。我意识到一次性连接会创建需要流式传输的额外数据,但我很惊讶这种控制级别不容易完成或者可能完全不可用。

2 个答案:

答案 0 :(得分:1)

Hibernate没有非常方便的动态提取方式。你可以通过

来控制它
  1. Dynamic fetching via HQL queriesjoin fetch一起使用(建议使用@ThibaultClement)。
  2. Dynamic association fetchingCriteria.setFetchMode()一起使用。
  3. Dynamic fetching via profiles@FetchProfile注释一起使用。
  4. 您也可以参考HQL joined query to eager fetch a large number of relationships了解其他想法。

答案 1 :(得分:0)

如@ v.ladynev所述,querydsl是一个不错的选择。但是,我认为仍然没有一种干净的方法来处理它。

  1. 如果使用.select(...),则结果将为元组而不是原始实体(未提及的字段默认为null),这将导致编写一些样板代码以将其映射到原始实体。
  2. 与querydsl相关的另一种可能的解决方案是使用QueryProjection,但同样需要您编写一个具有不同可能性的单独的类。
  3. 第三个解决方案可以是将所有联接保持为Fetch.LAZY,然后根据需要使用JpaUtils.initialize()(或hibernate自己的方法)来获取实体图。 (但是就性能而言,这比直接使用join fetch只会进行1次sql调用更糟糕)。
  4. 值得一提的另一种第三种选择是使用NamedEntityGraph或EntityGraph来获取所需的部分。