OneToMany 关系中的休眠标准

Posted

技术标签:

【中文标题】OneToMany 关系中的休眠标准【英文标题】:Hibernate Criterion in OneToMany relationship 【发布时间】:2015-01-23 15:47:36 【问题描述】:

我试图弄清楚当我检索父元素时如何使用休眠标准来获取一组特定的子元素。我创建了以下示例实体:

父类

@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;

休眠标准

getSession()
    .createCriteria(Parent.class)
    .createAlias("children", "c")
    .createAlias("c.gender", "g")
    .add(Restrictions.eq("g.genderInd", "M"))
    .list()

此条件为我提供了一个包含男性 (“M”) 孩子的父母列表,它会返回每个父母的所有孩子。我怎样才能得到一个有男性孩子的父母列表,并且只有 Parent.children 集中的男性孩子?

【问题讨论】:

你不能。如果您想要子集的子集,您可能不会搜索父母并向他询问他的孩子,因为当向父母询问他的孩子时,父母会返回他的孩子,所有这些孩子。相反,要找到孩子的子集,您需要搜索孩子。 @JBNizet 谢谢。我担心是这样的。 【参考方案1】:

我搜索了几天的解决方案,我遇到了同样的问题,我有一个带有翻译集合的对象,我想用唯一的当前语言查询一个对象。

我找到了这个解决方案: 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");

【讨论】:

这看起来会奏效,但我已经解决了这个问题。直到现在我才对过滤器一无所知,所以非常感谢!【参考方案2】:
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:在上面的例子中,我首先分别过滤掉有男孩的父母,然后过滤掉没有女孩的父母。之后我加入了限制和逻辑表达,这恰好给出了父母只有男孩的结果。 这并不完全符合我的要求。我确实想要有男孩的父母的结果,但我也希望父母实体只包含他们的男孩。

以上是关于OneToMany 关系中的休眠标准的主要内容,如果未能解决你的问题,请参考以下文章

@OneToMany 映射休眠中的集合

具有 OneToMany 关系的休眠重复条目

OneToMany /可为空关系的休眠性能问题

无法在休眠中删除 OneToMany 关系的实例

非主键之间的休眠关系OneToMany

无法使用 OneToMany 和 ManyToOne 关系在休眠中创建表(也无法创建外键)