我有一个JPA查询和以下实体:
产品可以有个人或团队。不是都。现在我想要一个查询,查找特定人员的所有产品,作为单个人,也可以作为团队成员(因此结果列表应包含两个案例)。所以我的查询结构如下:
public List<Product> getProductsFor(Person person){
CriteriaBuilder cb = getEntitymanager().getCriteriaBuilder();
CriteriaQuery<Product> query = cb.createQuery(Product.class);
Root<Product> root = query.from(Root.class);
Join<Product, Team> teamJoin = root.join(Product_.team, JoinType.LEFT);
Predicate asSinglePerson = cb.equal(root.get(Product_.person), person);
Predicate asTeamMember = cb.isMember(persons, teamJoin.get(Team_.members));
Predicate teamOrSingle = cb.or(asTeamMember, asSinglePerson);
query.where(teamOrSingle);
return getEntityManager().createQuery(query).getResultList();
}
但是,EclipseLink正在构建以下(Postgre)SQL代码:
SELECT t1.*
FROM
Product t1 LEFT OUTER JOIN team t2 ON (t2.ID = t1.team_ID),
team_person t3,
person t4
WHERE
(t1.person_ID = 1 OR t4.ID = 1)
AND t3.team_ID = t2.ID
AND t4.id = t3.person_ID
省略了一些括号,但查询是相同的。 此查询仅返回该人员是团队成员的产品,而不返回该人员作为一个人负责的产品。
我想要的是这样的:
SELECT t1.*
FROM
Product t1 LEFT OUTER JOIN team t2 ON (t2.ID = t1.team_ID),
team_person t3,
person t4
WHERE
t1.person_ID = 1
OR (t3.person_ID = t4.ID AND t3.team_ID = t2.ID AND t4.ID = 1)
由于OR-Operator是我查询中最外层的操作符,为什么它不能生成SQL?
将查询分为2个部分(一个用于团队部分,一个用于单个部分)不是一个选项,因为我们在这一个查询中内置了分页和过滤(这不会影响结果,所以我在列表中省略了它。
感谢您的帮助。
答案 0 :(得分:1)
'和'子句以任何方式与您的'或'语句无关,并且因为您用于构建查询的连接语义而存在。关系的'get'是使用内连接定义的,需要过滤结果,这些连接可以在From子句中完成,也可以附加到where子句。
您需要在team.members关系中明确使用Left outer join来获取您要查找的查询结果,类似于您完成product.team关系的方式。