如何使用 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 加载实体列表和这些实体相关实体的子集?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用本机 SQL 在 Hibernate 中获取仅包含选定列的表实体列表?
使用 JPA 和 Spring 加载选定的 Hibernate 实体