Hibernate是如何决定默认使用哪种FetchMode的?

7
在我们的项目中,我们使用Hibernate,在日志中观察到它有时会在关系中使用Join,有时使用Select(我认为这是FetchMode),当我们没有指定FetchMode时。
如果没有指定FetchMode,Hibernate如何决定使用哪个FetchMode?
有没有针对此的规范?任何代码行?任何文章?

http://www.solidsyntax.be/2013/10/17/fetching-collections-hibernate/ - Steephen
在FetchMode中有“when”(Lazy,Eager)和“how”(Select,Join等)之分。看起来你对“how”比较感兴趣。试着阅读官方文档,里面有一些关于默认模式的细节。 - aUserHimself
3个回答

16
如果在字段上未添加Hibernate注释@Fetch,则该字段的默认FetchMode为:
  • 如果此字段的FetchType = EAGER,则FetchMode = JOIN。
  • 否则,FetchMode = SELECT。
我的信息来源是代码本身(Hibernate 5.0):这里这里和最重要的这里

FetchMode 还取决于查询方式(Session.get、Criteria API、JPQL)。请参见我的回答 https://dev59.com/V5zha4cB1Zd3GeqPJ8Ah#61430192。 - Eugene Khyst

2

如果一个字段没有使用@Fetch注解,那么该字段的默认FetchMode取决于FetchType和查询方式:

  • FetchType.LAZY => FetchMode.SELECT
  • FetchType.EAGER
    • 通过ID获取(Session.get) => FetchMode.JOIN
    • JPQL 查询 => FetchMode.SELECT
    • Criteria API 查询 => FetchMode.SELECT

1
我喜欢这个架构,因为它强调了在JPQL或Criteria查询的情况下,FetchMode是由查询中的连接/获取方式或没有这些方式来覆盖的。 - Fabio Formosa

1
当未指定FetchMode且FetchType为EAGER时,查看生成的SQL语句,默认情况下Hibernate使用JOIN。遗憾的是,我在官方文档中找不到这些信息。关于即使默认情况下使用JOIN也使用SELECT的情况,我认为有一些查询无法在单个查询中解决,例如这样

但是如果您允许B没有C,则Hibernate在加载B时必须检查C的存在。但是,用SELECT检查存在性只是低效的,因为同一个SELECT不仅可以检查存在性,还可以加载整个对象。所以懒加载就消失了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接