【问题标题】:How hibernate decide which of FetchMode use by default?hibernate 如何决定默认使用哪个 FetchMode?
【发布时间】:2016-11-23 10:46:06
【问题描述】:

在我们的项目中,我们使用 Hibernate,在日志中我们观察到,当我们没有指定 FetchMode 时,它​​有时使用 Join,有时使用 Select 来表示关系(据我所知是 FetchMode)。

如果没有指定,Hibernate 如何决定使用哪一种 FetchMode?​​p>

对此有任何规范吗?有几行代码?有文章吗?

【问题讨论】:

标签: java hibernate jpa-2.0


【解决方案1】:

如果某个字段上不存在 Hibernate 注释 @Fetch,则该字段的默认 FetchMode 为:

  • 如果此字段的 FetchType = EAGER,则 FetchMode = JOIN。
  • 否则,FetchMode = SELECT。

我获取此信息的来源是代码本身(Hibernate 5.0):HEREHERE,最重要的是HERE

【讨论】:

【解决方案2】:

在没有指定FetchMode且FetchType为EAGER时查看生成的SQL,Hibernate默认为JOIN

很遗憾,我在官方文档中找不到此信息。

关于SELECT 的使用,即使JOIN 是默认值,我认为这是一些无法在单个查询中解决的查询,like this

但是如果你允许 B 没有 C,Hibernate 只需要检查是否存在 C 在加载 B 的那一刻。但是检查存在的 SELECT 只是 效率低下,因为同一个 SELECT 可能不仅检查存在,而且 加载整个对象。所以延迟加载消失了。

【讨论】:

    【解决方案3】:

    如果一个字段没有用@Fetch注解,那么这个字段的默认FetchMode取决于FetchType和查询是如何完成的:

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

    【讨论】:

    • 我喜欢这个模式,因为它强调了在 JPQL 或 Criteria 查询的情况下,FetchMode 会被查询在 join/fetch 方面的完成方式所覆盖,或者没有这些。
    猜你喜欢
    • 2016-10-25
    • 1970-01-01
    • 1970-01-01
    • 2019-06-06
    • 1970-01-01
    • 2011-10-11
    • 1970-01-01
    • 1970-01-01
    • 2011-06-07
    相关资源
    最近更新 更多