Java 使用Hibernate一次高效加载大量OneToMany集合

Java 使用Hibernate一次高效加载大量OneToMany集合,java,hibernate,Java,Hibernate,我有一个父实体与@OneToMany关系的子实体实体。大多数情况下,当我需要处理父级的子级实体时,我使用的是单个父级,因此延迟获取(FetchMode.SELECT)是合适的 但是,我有一种情况,我查询大量的父对象s(有时数百甚至数千),我需要处理它们的子对象实体FetchMode.SELECT给了我一个严重的N+1问题,所以在这个场景中我需要做一些不同的事情。如果我是通过JDBC执行此操作的,它将是对父记录的单个查询,然后使用IN语句(where Child.parentid IN(?,?…)

我有一个
父实体
@OneToMany
关系的
子实体
实体。大多数情况下,当我需要处理父级的子级实体时,我使用的是单个父级,因此延迟获取(
FetchMode.SELECT
)是合适的

但是,我有一种情况,我查询大量的
父对象
s(有时数百甚至数千),我需要处理它们的
子对象
实体
FetchMode.SELECT
给了我一个严重的N+1问题,所以在这个场景中我需要做一些不同的事情。如果我是通过JDBC执行此操作的,它将是对
父记录的单个查询,然后使用
IN
语句(
where Child.parentid IN(?,?…)
)对所有
子记录的另一个查询。我需要活动的Hibernate实体,因为Hibernate搜索将调用getChildren()作为其索引过程的一部分

我考虑过的选项有:

  • Criteria.setFetchMode(“children”,FetchMode.JOIN)
    (或HQL中的
    JOIN-fetch
    )——这会给我一个笛卡尔乘积,但它对那么多实体来说是残酷的
  • @BatchSize
    添加到
    Parent.getChildren()
    -这将有助于我的大批量场景,但这并不是我想要用于正常操作的策略。如果我能在Criteria/HQL中为获取设置一个批大小,那就太完美了,但我找不到这样做的方法
  • Parent.getChildren()
    中使用
    FetchMode.SUBSELECT
    ——与
    @BatchSize
    非常相似,这对于我的大批量场景非常有用,但不适合正常操作,而且我找不到方法将其与Criteria/HQL一起使用(尽管名称重复,但条件和实体注释使用不同的FetchMode枚举)

  • tldr;我有一个一对多的关系,采用延迟获取模式,但有时我希望能够同时有效地加载多个实体的关系。

    1.我看不出有什么比JDBC更能阻止您在JPA查询中执行相同的操作;2.我不明白为什么笛卡尔积会如此残酷。假设您ave 500个父项,每个父项有10个子项,IN查询将加载5000行,而join fetch查询将加载…5000行。1.Hibernate搜索需要Parent.getChildren()为了容纳子记录,这就是为什么我不能单独查询子记录的原因。我更新了问题以澄清这一点。2.问题不是行数,而是多次检索同一父记录的所有数据(列数非常多)当查询结果变得非常大和/或查询变得非常复杂时,我只是通过
    createNativeQuery()使用本机查询
    就这样吧。Hibernate使用方便,但很快就会变得效率低下。哈,我也有同感。遗憾的是,我们正在使用Hibernate搜索进行索引,我需要向它发送真实的父实体,它将调用getChildren()。所以我需要一种方法来有效地填充这种关系,否则我将处于“N+1地带”(迪斯尼世界最不受欢迎的公园)