我有一个查询,我想要在桌子上运行,让我们称之为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
集合填充了我感兴趣的两个(或更少,因为它们是可选的)实体?
答案 0 :(得分: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);;
}
希望能解决你的问题。