JPA 2条件API中的SELECT DISTINCT + ORDER BY

pokxtpni  于 2022-11-14  发布在  其他
关注(0)|答案(2)|浏览(129)

我有一个类Lawsuit,它包含一个List<Hearing>,每个List<Hearing>都有一个Date属性。
我需要选择按Hearing日期排序的所有Lawsuit
我有一个条件查询,如

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

我使用distinct将结果扁平化:

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

然后把LawsuitHearing连接起来

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

创建Predicate

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

Order S:

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

如果我避免使用distinct,一切都正常,但如果我使用它,它会抱怨无法基于不在SELECT:
错误原因:错误:对于SELECT DISTINCTORDER BY表达式必须出现在选择列表中
List<Hearing>已经可以通过返回的Lawsuit类访问,所以我很困惑:如何将它们添加到选择列表中?

rvpgvaaj

rvpgvaaj1#

我已经在别的地方发现了问题的根源,解决了它就没有必要做问题中所问的事情;如其他答案所述,此处不需要执行distinct
重复的行是由错误的left join引起的,即使没有使用 predicate ,这些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()));
}

所以,如果您来这里是因为遇到了同样的问题,请在连接中搜索问题

cgvd09ve

cgvd09ve2#

也可以根据根表的主键列,通过group by进行重复删除:

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

相关问题