我的父母与子表有一个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;
};
}
答案 0 :(得分:4)
我担心,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);
答案 1 :(得分:0)
当您创建JOIN
时(特别是当属性是集合类型,而不是SingularAttribute
时,您必须使用它来构建条件,因此请使用
cb.equal(children.get("sex"), "MALE").
而不是
cb.equal(parent.get("children").get("sex"), "MALE").
答案 2 :(得分:0)
对于将来的引用,这来自另一篇帖子,对我(link)有所帮助: 代替parent.joinSet,使用fetch,然后将其强制加入:
output$tab1 <- renderTable({
if (input$submit_kwic== 0){return()}
else{
isolate({
validate(
need(input$word1 !='',"No table output shown as word 1 is not supplied"),
need(sum(grepl(input$word1, x = attr(tokens_wo_stp, "types"))) >= 1,"Word does not exist in vocabulary, try another word!")
)
table1()
})
}}, striped = TRUE, hover = TRUE, bordered = TRUE)
正如上面链接中提到的那样,这不是完美的解决方案,但它为我省去了很多麻烦。