在JPA 2 Criteria API中选择DISTINCT + ORDER BY

时间:2016-06-29 09:06:49

标签: java postgresql jpa jpa-2.0 criteria-api

我有一个班级Lawsuit,其中包含List<Hearing>,每个班级都有一个Date属性。

我需要选择按Lawsuit的日期排序的所有Hearing

我有像CriteriaQuery那样的

CriteriaBuilder           cb = em.getCriteriaBuilder();
CriteriaQuery<Lawsuit>    cq = cb.createQuery(Lawsuit.class);
Root<Lawsuit>           root = cq.from(Lawsuit.class);

我使用不同来展平结果:

cq.select(root).distinct(true);

然后加入 Lawsuit Hearing

Join<Lawsuit, Hearing> hearing = root.join("hearings", JoinType.INNER);

创建Predicate s

predicateList.add(cb.isNotNull(hearing.<Date>get("date")));

Order s:

orderList.add(cb.asc(hearing.<Date>get("date")));

如果我避免distinct,一切正常,但如果我使用它,它会抱怨无法根据SELECT中没有的字段进行排序:

  

引起:org.postgresql.util.PSQLException:错误:对于SELECT DISTINCT ORDER BY表达式必须出现在选择列表中

List<Hearing>已经可以通过返回的Lawsuit类访问了,所以我很困惑:我应该如何将它们添加到选择列表中?

2 个答案:

答案 0 :(得分:5)

我已经在其他地方发现了问题的根源,而解决问题却没有必要去做问题中的问题; 如其他答案所述,不必在此处执行distinct

重复的行是由对集合(根对象的属性)执行的错误left join发起的,即使没有使用谓词:

Join<Lawsuit, Witness> witnesses = root.join("witnesses", JoinType.LEFT);
if (witnessToFilterWith!=null) {
    predicateList.add(cb.equal(witnesses.<Long>get("id"),witnessToFilterWith.getId()));
}

join显然应该只在inner执行,只在需要时执行

if (witnessToFilterWith!=null) {
    Join<Lawsuit, Witness> witnesses = root.join("witnesses", JoinType.INNER);
    predicateList.add(cb.equal(witnesses.<Long>get("id"),witnessToFilterWith.getId()));
}

所以,如果你因为问题得到了解决,在联接中搜索问题

答案 1 :(得分:0)

您还可以根据根表的主键列从组中删除重复:

 cq.groupBy(root.get("id")); // Assuming that Lawsuite.id is primary key column