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

Java 如何使用Hibernate加载实体列表和这些实体的子集';相关实体?,java,hibernate,outer-join,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 S

我想对一个表运行一个查询,让我们称之为
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;
    //...
}
我可以在Hibernate中这样做,只需从第一个查询中获取结果并在
children
集合中迭代以查找我想要的行,但这是非常低效的:一个查询执行两个外部联接,而一个查询+每个查询一个额外的查询来查找我关心的孩子


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

您不需要两个外部联接。您可以简单地使用此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);;
}
List parentList=会话
.createQuery(“从父级p左连接获取p.children c”+
“其中p.status=‘完成’”+
“和(c.key='FIRST_key'或c.key='SECOND_key')”)
.setResultTransformer(标准.DISTINCT\u ROOT\u实体)
.list();
用于(父项:父项列表){
System.out.println(父项);;
}

希望这能解决您的问题。

谢谢您的帮助。我接受这个解决方案,但经过大量研究,我发现我需要的是能够在连接上指定一个“on”子句来限制外部连接表。Hibernate通过
with
子句支持这一点,但这对我也不起作用。获取
antlr.SemanticException:with子句不允许在获取的关联上使用;使用过滤器
。如果您确定值将存在于外部联接表中,那么您的解决方案将起作用。如果记录可能不在那里,查询将无法检索到您期望的记录。
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);;
}