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

时间:2015-10-21 16:44:46

标签: java hibernate outer-join

我有一个查询,我想要在桌子上运行,让我们称之为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 个答案:

答案 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);;
}

希望能解决你的问题。