Hibernate Criteria 在 OneToMany 关系中的应用

3
我正在尝试找出如何使用Hibernate标准来获取特定集合的子元素,当我检索父元素时。 我已经创建了以下示例实体: 父类
@Entity
public class Parent {
    @Id
    @Column(name="PARENT_ID")
    private long parentId;

    @Column(name="NAME")
    private String name;

    @OneToMany(mappedBy="parent")
    private Set<Child> children
}

子类

@Entity
public class Child {
    @Id
    @Column(name="CHILD_ID")
    private long childId

    @ManyToOne
    @JoinColumn(name="PARENT_ID")
    private Parent parent;

    @ManyToOne
    @JoinColumn(name="GENDER_ID")
    private Gender gender;
}

性别班级
@Entity
public class Gender {
    @Id
    @Column(name="GENDER_ID")
    private long genderId;

    @Column(name="GENDER_IND")
    private String genderInd;
}

Hibernate Criteria(Hibernate标准查询)
getSession()
    .createCriteria(Parent.class)
    .createAlias("children", "c")
    .createAlias("c.gender", "g")
    .add(Restrictions.eq("g.genderInd", "M"))
    .list()

这个条件给了我一个父母列表,其中有男孩(“M”),并返回每个父母的所有子女。如何获取仅具有父母.children集合中男孩子的男孩父母列表?

你不能这样做。如果你想要子集,你不能搜索父级并询问他的子集,因为当询问父级时,父级会返回他的所有子集。相反,要找到子集,你需要搜索子集本身。 - JB Nizet
@JBNizet 谢谢。我担心那就是情况。 - LucasP
2个回答

4
我搜索了好几天才找到解决方案,我遇到了同样的问题。我的对象里有一组翻译内容,我希望只查询当前语言的对象。
我找到了这个解决方案: https://docs.jboss.org/hibernate/orm/3.6/reference/en-US/html/filters.html
这个方法对我有效,以下是给你的解决方案:
@Entity
public class Parent {
    @Id
    @Column(name="PARENT_ID")
    private long parentId;

    @Column(name="NAME")
    private String name;

    @OneToMany(mappedBy="parent")
    @Filter(name="gender", condition="gender.genderInd=:gender")
    private Set<Child> children
}

@Entity
@FilterDef(name="genderFilter", parameters=@ParamDef( name="gender", type="string" ) )
public class Child {
    @Id
    @Column(name="CHILD_ID")
    private long childId

    @ManyToOne
    @JoinColumn(name="PARENT_ID")
    private Parent parent;

    @ManyToOne
    @JoinColumn(name="GENDER_ID")
    private Gender gender;
}

在执行查询之前:
Session session = sessionFactory.getCurrentSession();
session.enableFilter("genderFilter").setParameter("gender", "M");

这看起来本来可以工作,但我已经解决了这个问题。直到现在我才知道过滤器的事情,非常感谢! - LucasP

1
Criteria cr = getSession()
            .createCriteria(Parent.class)
            .createAlias("children", "c")
            .createAlias("c.gender", "g");

Criterion Malechild = Restrictions.eq("g.genderInd", "M");

Criterion NFemaleChild = Restrictions.ne("g.genderInd", "F");

LogicalExpression andExp = Restrictions.and(Malechild, NFemaleChild);

cr.add(andExp);

List results = cr.list();

提供一些关于你提交的代码的解释是很好的。 - George Netu
1
@ George Netu:在上面的例子中,我首先单独筛选出了有男孩子的父母,然后筛选出没有女孩子的父母。之后,我使用逻辑与表达式将两个限制条件结合起来,这正好给出了只有男孩子的父母的结果。 - Kavita Saini
这并不完全符合我的要求。我确实想要具有男性子女的父母的结果,但我还希望Parent实体仅包含他们的男性子女。 - LucasP

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接