JPA Criteria Builder OneToMany限制

问题描述 投票:4回答:3

我有一个父子与OneToMany关联与子表。

我正在尝试使用CriteriaBuilder编写查询来限制从Child表返回的结果。

我正在添加谓词,类似于

cb.equal(parent.get("children").get("sex"), "MALE")

如果父母有一个儿子或者SON和女儿它正在返回那个父母,但也返回他们拥有的所有孩子。

Hibernate使用我的谓词触发第一个查询,但第二个查询以获取子节点仅使用where子句中不包含的JoinColumn

cb.equal(parent.get("children").get("sex"), "MALE").

思考?

我正在使用SetJoin

children = parent.joinSet("children", JoinType.LEFT)

澄清:

public static Specification<Parent> findPlanBenefits(Integer parentId) {
    return (parent, query, cb) -> {
        Predicate predicates = cb.conjunction();
        List<Expression<Boolean>> expressions = predicates.getExpressions();

        //Parent Criteria
        expressions.add(cb.equal(parent.get("parentId"), parentId));

        //Children Criteria
        SetJoin<Parent, Children> children = parent.joinSet("children", JoinType.LEFT);

        Predicate sex = cb.equal(children.get("sex"), "MALE");
        children.on(sex);

        return predicates;
    };
}
java jpa one-to-many
3个回答
4
投票

我担心,JOIN ON不能像你期望的那样在你的答案中工作。 JOIN ON只告诉如何加入,而不是如何加载关系。

因此,为了解决您的问题,您必须在加载后过滤子项,或者使用单独的查询手动获取所有男性子项。

为了检查JOIN ON的工作原理,您还可以尝试相应的JPQL查询。


UPDATE

OP告诉JPQL queryselect p from parent p join fetch children c where p.parentId = :parentId and c.sex = "MALE"有效。

相应的CriteriaQuery看起来像:

CriteriaQuery<Parent> criteria = cb.createQuery((Class<Parent>) Parent.class);
Root<Parent> parent = criteria.from(Parent.class);

criteria.select((Selection<T>) parent);
SetJoin<Parent, Children> children = parent.joinSet("children", JoinType.LEFT);

Predicate sexPredicate = cb.equal(children.get("sex"), "MALE");
parent.fetch(children);
//parent.fetch("children");//try also this

criteria.where(sexPredicate);

0
投票

当你创建一个JOIN时(特别是当属性是集合类型,而不是SingularAttribute时,你必须用它来构建标准,所以使用

cb.equal(children.get("sex"), "MALE").

代替

cb.equal(parent.get("children").get("sex"), "MALE").

0
投票

为了将来的参考,这是来自另一个帖子,帮助我(link):而不是parent.joinSet使用fetch然后将其转换为join:

Join<Parent, Children> join = (Join<Parent, Children>)parent.fetch(Parent_.children);

正如上面链接的帖子中提到的那样,它并不是完美的解决方案,但它让我很烦恼。

© www.soinside.com 2019 - 2024. All rights reserved.