我有一个包含元素列表的实体,现在我想搜索这些元素的属性。这个约束应该是"和"连接的。请看这些简单的例子:
@Entity
public class Parent {
@Column
@Enumerated(EnumType.STRING)
private City city;
@OneToMany(...)
private List<Children> childrens;
}
@Entity
public class Children {
@Column
@Enumerated(EnumType.STRING)
private School school;
@Column
private Integer yearInSchool;
}
现在我想在某个城市找到父母,让我们说&#34; BigCity&#34;和孩子一起上学&#34; AwesomeSchool&#34;这是在课堂/第6年。我想通过CriteriaBuilder获得搜索结果。
到目前为止,我得到了:
final CriteriaBuilder c = getCriteriaBuilder();
final CriteriaQuery<Parent> query = c.createQuery(Parent.class);
final Root<Parent> r = query.from(Parent.class);
query.select(r)
.where(c.and(c.equal(r.get("city"), City.BigCity)),
c.equal(r.get("childrens").get("school"), School.AwesomeSchool),
c.equal(r.get("childrens").get("yearInSchool"), 6));
不幸的是,这里有两个问题:
- 看起来我无法在list属性上调用get("school")
- 这将归还所有有孩子的父母,这些孩子要么在#Aw ;; AwesomeSchool&#34;或者在学校6年。
where
部分,以便它认为必须同时满足两个属性(school和yearInSchool)。
我找到了关于查询孩子满足一个条件的对象的类似帖子 - 但是这里孩子们必须同时满足两个条件。
更新1 如果我使用联接断言,例如&#34;学校&#34;一个孩子,我到目前为止关于谓词:
Predicate predicate = r.join("childrens").get("school").in(School.AwesomeSchool)
如何重用此连接对象断言也适用于第二个过滤条件?
答案 0 :(得分:3)
您需要JOIN
,然后在形成JOIN
子句时使用形成联接时获得的WHERE
对象。
Join childrenJoin = r.join("childrens");
query.where(c.and(c.equal(r.get("city"), City.BigCity)),
c.equal(childrenJoin.get("school"), School.AwesomeSchool),
c.equal(childrenJoin.get("yearInSchool"), 6));
也许你的意思是你的JPQL:
SELECT p FROM Parent p JOIN p.childrens c
WHERE p.city = :theCity AND c.school = :theSchool AND c.yearInSchool = 6