EclipseLink正在重新排序谓词?

时间:2014-06-24 12:54:29

标签: postgresql jpa eclipselink java-ee-7

我有一个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个部分(一个用于团队部分,一个用于单个部分)不是一个选项,因为我们在这一个查询中内置了分页和过滤(这不会影响结果,所以我在列表中省略了它。

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

'和'子句以任何方式与您的'或'语句无关,并且因为您用于构建查询的连接语义而存在。关系的'get'是使用内连接定义的,需要过滤结果,这些连接可以在From子句中完成,也可以附加到where子句。

您需要在team.members关系中明确使用Left outer join来获取您要查找的查询结果,类似于您完成product.team关系的方式。