hel*_*ity 4 java jpa one-to-many
我有一个父母与一个孩子表的OneToMany关联。
我正在尝试使用CriteriaBuilder编写查询,以限制从Child表返回的结果。
我要添加一个谓词,例如
cb.equal(parent.get("children").get("sex"), "MALE")
Run Code Online (Sandbox Code Playgroud)
如果父母有儿子或儿子和女儿,则是在返还该父母的同时还返还他们所有的孩子。
Hibernate使用我的谓词触发第一个查询,但是第二个获取子项的查询仅在不包含where子句的情况下使用JoinColumn
cb.equal(parent.get("children").get("sex"), "MALE").
Run Code Online (Sandbox Code Playgroud)
有什么想法吗?
我正在使用SetJoin
children = parent.joinSet("children", JoinType.LEFT)
Run Code Online (Sandbox Code Playgroud)
澄清:
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;
};
}
Run Code Online (Sandbox Code Playgroud)
恐怕,JOIN ON它不能按您期望的那样工作。JOIN ON仅告诉如何加入,而不告诉如何加载关系。
因此,为了解决您的问题,您将必须在加载子项后对其进行过滤,或者使用单独的查询手动获取所有男子项。
为了检查JOIN ON工作原理,您还可以尝试相应的JPQL查询。
更新
OP告知JPQL查询select 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);
Run Code Online (Sandbox Code Playgroud)
当您创建一个JOIN(特别是当属性是集合类型而不是 时SingularAttribute,您必须使用它来构建条件,因此使用
cb.equal(children.get("sex"), "MALE").
Run Code Online (Sandbox Code Playgroud)
代替
cb.equal(parent.get("children").get("sex"), "MALE").
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7991 次 |
| 最近记录: |