SELECT JPA 2 条件中的 DISTINCT + ORDER BY API
SELECT DISTINCT + ORDER BY in JPA 2 Criteria API
我有一个 class Lawsuit
,其中包含一个 List<Hearing>
,每个都有一个 Date
属性。
我需要 select 所有 Lawsuit
按 Hearing
日期排序
我有一个像
这样的 CriteriaQuery
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Lawsuit> cq = cb.createQuery(Lawsuit.class);
Root<Lawsuit> root = cq.from(Lawsuit.class);
我使用distinct来压平结果:
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:
中的字段进行排序
Caused by: org.postgresql.util.PSQLException: ERROR: for SELECT DISTINCT
, ORDER BY
expressions must appear in select list
List<Hearing>
已经可以通过返回的 Lawsuit
classes 访问,所以我很困惑:我应该如何将它们添加到 select 列表 ?
我在别处发现了问题的根源,解决了问题就没有必要做问题中的要求了;
正如其他答案中所述,这里应该没有必要执行 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()));
}
因此,如果您是因为遇到同样的问题来到这里,请在联接中搜索问题。
也可以根据根的主键列通过group by去重table:
cq.groupBy(root.get("id")); // Assuming that Lawsuite.id is primary key column
我有一个 class Lawsuit
,其中包含一个 List<Hearing>
,每个都有一个 Date
属性。
我需要 select 所有 Lawsuit
按 Hearing
我有一个像
这样的 CriteriaQueryCriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Lawsuit> cq = cb.createQuery(Lawsuit.class);
Root<Lawsuit> root = cq.from(Lawsuit.class);
我使用distinct来压平结果:
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:
Caused by: org.postgresql.util.PSQLException: ERROR: for
SELECT DISTINCT
,ORDER BY
expressions must appear in select list
List<Hearing>
已经可以通过返回的 Lawsuit
classes 访问,所以我很困惑:我应该如何将它们添加到 select 列表 ?
我在别处发现了问题的根源,解决了问题就没有必要做问题中的要求了;
正如其他答案中所述,这里应该没有必要执行 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()));
}
因此,如果您是因为遇到同样的问题来到这里,请在联接中搜索问题。
也可以根据根的主键列通过group by去重table:
cq.groupBy(root.get("id")); // Assuming that Lawsuite.id is primary key column