ORDER BY in Criteria API 用于计算列名称(按别名)

ORDER BY in Criteria API for a computed column name (by alias)

遇到我的java代码是符号查询的情况-

  SELECT CUSTOMER_ID,
         CUSTOMER_NAME,
         CASE
             WHEN COUNT (DISTINCT CARD_ID) > 1 THEN 'MULTIPLE'
             ELSE MAX(CARD_NUM)
         END    AS CARD_NUM
    FROM CUSTOMER LEFT JOIN CARD ON CARD.CUSTOMER_ID = CUSTOMER.CUSTOMER_ID
GROUP BY CUSTOMER_ID, CUSTOMER_NAME

Java 详细信息代码 -

CriteriaBuilder cb = em.getCriteriaBuilder();
final CriteriaQuery<Tuple> query = cb.createQuery(Tuple.class);
final Root<Customer> root = query.from(Customer.class);
Expression<Object> caseSelect = cb.selectCase()
        .when(cb.greaterThan(cb.countDistinct(join.get(Card_.cardId)), 1L), "MULTIPLE")
        .otherwise(cb.greatest(Card_.get(Card_.cardNum)));
caseSelect.alias("card_num");
selects.add(caseSelect);
query.multiselect(selects).distinct(true);
query.groupBy(exprs);
query.orderBy(cb.asc(caseSelect));

现在,如何根据标准 API 进行排序。

  1. 如果我使用 orderby root.CARD_NUM,该属性不存在于 Root 中。- 抛出异常。
  2. 如果我按 caseSelect 表达式本身排序,它会抛出错误 说明 CARD_ID 不在查询的 SELECTED 部分。
  3. 我不能在 select 表达式中包含 card_num / card_id,这不适合查询。

有什么方法可以只按别名排序吗?我看到 Order 是 Expression 类型,以及如何从字符串名称中获取表达式。我猜你可以在 Hibernate 中做到这一点。无论如何都可以在标准 API 中使用休眠 orderby 吗?猜个傻q

感谢任何帮助。

JPA 标准 API 似乎无法做到这一点,您将不得不退而求其次,改为使用 JPQL/HQL。

这是不可能的,感觉就像是 JPA 遗漏了一个案例。 虽然如果使用休眠 API 是可能的。但是,我的解决方法是 -

  1. 创建了一个包含 case 表达式的视图。
  2. 用我的实体加入视图(你不能加入,但是再加入一个 query.from(View.class)).
  3. 在where中添加视图和实体的id。

现在在顺序中您可以通过 View.column_name 提及列名称。

使用条件 API,您需要按 caseSelect 表达式排序。我试了一下,它在 Hibernate 5.4 上运行良好。您使用哪个版本?

我遇到过类似的情况...

query.multiselect(root, computedColumn);
query.orderBy(new Order[]{filterDTO.getSortAsc() ? cb.asc(cb.literal(2)) : cb.desc(cb.literal(2))});

我的情况是 computedColumn 是子查询...我没有设法让它按列别名工作,但它似乎按元组中返回的列索引工作,所以我猜在你的代码中它应该按索引 1

query.orderBy(cb.asc(cb.literal(1)));