如何使用 Hibernate 加载实体列表和这些实体相关实体的子集?

Posted

技术标签:

【中文标题】如何使用 Hibernate 加载实体列表和这些实体相关实体的子集?【英文标题】:How can I use Hibernate to load a list of entities and a subset of those entities' related entities? 【发布时间】:2016-01-20 18:41:41 【问题描述】:

我有一个查询,我想针对一个表运行,我们称它为parent,我在其中抓取所有符合特定条件的行。在 SQL 中:

select * from parent where status = 'COMPLETE';

我将这个表和另一个相关表 (child) 定义为 Hibernate 实体,这样:

@Entity
@Table(name = "parent")
public class Parent 
    //...
    @OneToMany(mappedBy = "parent")
    private Set<Child> children;
    //...


@Entity
@Table(name = "child")
public class Child 
    //...
    @ManyToOne
    @JoinColumn(name = "parent_id")
    private Parent parent;

    @Column(name = "key")
    private String key;
    //...

我希望我的查询还提取两个可选子记录,其中key 是两个值之一。所以,在 SQL 中:

select *
from parent p, child ca, child cb
where p.status = 'COMPLETED'
and p.id *= ca.parent_id
and ca.key = 'FIRST_KEY'
and p.id *= cb.parent_id
and cb.key = 'SECOND_KEY';

我可以在 Hibernate 中执行此操作,只需从第一个查询中获取结果并遍历 children 集合以查找我想要的行,但这非常低效:一个查询执行两个外部连接 vs 一个查询 + 一个附加查询每个寻找我关心的孩子。

有没有办法在 Hibernate 中复制上述查询中的外连接,其中返回的对象将只有 children 集合填充我感兴趣的两个(或更少,因为它们是可选的)实体?

【问题讨论】:

【参考方案1】:

您不需要两个外连接。您可以简单地使用此 HQL,Hibernate 会将正确的子代添加到正确的父代:

List<Parent> parentList = session
        .createQuery("from Parent p left join fetch p.children c" +
                     " where p.status = 'COMPLETE' " + 
                     " and (c.key = 'FIRST_KEY' or c.key = 'SECOND_KEY')")
        .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
        .list();

for(Parent parent:parentList) 
    System.out.println(parent);;

希望能解决您的问题。

【讨论】:

感谢您的帮助。我接受了这个解决方案,但经过大量研究,事实证明我需要的是能够在连接上指定一个“on”子句来限制外部连接表。 Hibernate 通过 with 子句支持这一点,但这对我也不起作用。获取antlr.SemanticException: with-clause not allowed on fetched associations; use filters。如果您确定值将存在于外部连接表中,您的解决方案将起作用。如果记录可能不存在,查询将不会检索到您期望的记录。

以上是关于如何使用 Hibernate 加载实体列表和这些实体相关实体的子集?的主要内容,如果未能解决你的问题,请参考以下文章

Hibernate延迟加载机制

Hibernate延迟加载

如何使用本机 SQL 在 Hibernate 中获取仅包含选定列的表实体列表?

使用 JPA 和 Spring 加载选定的 Hibernate 实体

如何使用 JPA 和 Hibernate 连接两个不相关的实体

实体列表的 CriteriaBuilder 和 isMember (Hibernate)