繁体   English   中英

休眠条件 OneToOne FetchType.Eager FetchMode.Join 执行不必要的查询

[英]Hibernate criteria OneToOne FetchType.Eager FetchMode.Join execute unnecessary queryes

我有示例实体 TableA 和 TableB,在表 A 中,我们有列 TABLE_B_ID 注释如下:

@OneToOne(fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "TABLE_B_ID")
@Fetch(FetchMode.JOIN)

然后当我执行这样的简单代码时:

Criteria c = session.createCriteria(TableA.class);
c.list();

Hibernate 运行查询 n+1 次,其中表 A 中的 n=行数,即使在第一次查询时 TableA 已经与 TableB 连接,Hibernate 仍然试图通过另一个选择查询为每个 A 获取 TableB。

查询已触发:

Hibernate: 
select
    this_.id as id1_0_1_,
    this_.name as name2_0_1_,
    this_.TABLE_B_ID as TABLE_B_3_0_1_,
    tableb2_.id as id1_1_0_,
    tableb2_.name as name2_1_0_ 
from
    TABLE_A this_ 
inner join
    TABLE_B tableb2_ 
        on this_.TABLE_B_ID=tableb2_.id
Hibernate: 
    select
        tablea0_.id as id1_0_1_,
        tablea0_.name as name2_0_1_,
        tablea0_.TABLE_B_ID as TABLE_B_3_0_1_,
        tableb1_.id as id1_1_0_,
        tableb1_.name as name2_1_0_ 
    from
        TABLE_A tablea0_ 
    inner join
        TABLE_B tableb1_ 
            on tablea0_.TABLE_B_ID=tableb1_.id 
    where
        tablea0_.TABLE_B_ID=?
Hibernate: 
    select
        tablea0_.id as id1_0_1_,
        tablea0_.name as name2_0_1_,
        tablea0_.TABLE_B_ID as TABLE_B_3_0_1_,
        tableb1_.id as id1_1_0_,
        tableb1_.name as name2_1_0_ 
    from
        TABLE_A tablea0_ 
    inner join
        TABLE_B tableb1_ 
            on tablea0_.TABLE_B_ID=tableb1_.id 
    where
        tablea0_.TABLE_B_ID=?

等等..

我已经尝试删除FetchMode或更改optional=true但触发的查询仍然是 n+1 次。 即使在他已经获得第一个选择查询的数据后,休眠触发另一个选择的原因是什么?

您遇到了一个众所周知的问题,当您选择父实体时会出现“N+1 选择”问题,并且休眠将使用 OneToOne 为与父实体相关的子实体进行额外的选择。 因此,如果您在数据库中有“N”条父子记录,hibernate 将获得所有父级的一个选择,然后将每个子级置于单独的选择中,总共 N+1 个选择。 Hibernate 中的“N+1”问题有两种解决方法: 1. “Join Fetch”所有 OneToOne 孩子。 2.启用二级缓存,并在OneToOne子节点上使用@Cache注解。

您的问题是您没有“加入获取”所有 OneToOne 孩子。 您必须“加入获取”所有这些,包括可传递的子项(从子项本身或集合中引用的实体)。

使 OneToOne 懒惰(因为默认情况下它是渴望的)只是部分解决方案,因为只有当您访问孩子的某些 getter 时,hibernate 才会为孩子进行选择,但从长远来看,它仍然会进行所有 N 次选择。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM