【问题标题】:Java Persistence Criteria API - case expressions in orderBy()Java Persistence Criteria API - orderBy() 中的案例表达式
【发布时间】:2016-05-19 13:48:37
【问题描述】:

如果不为空,我需要按一个字段对我的查询结果进行排序,否则按另一个字段排序。

这是我的代码:

Expression condizione=cb.isNotNull(root.get(Attribuzione_.dataprincipale));
Expression principale=root.get(Attribuzione_.dataprincipale);
Expression creato=root.get(Attribuzione_.recordcreato);
Order ord=cb.desc(cb.selectCase()
        .when(condizione, principale)
        .otherwise(creato));
cq=cq.orderBy(ord);

此代码导致Internal Exception: org.postgresql.util.PSQLException 因为 SQL 代码中的翻译不是我需要的“排序依据”:

ORDER BY CASE WHEN (t0.dataprincipale IS NOT NULL) THEN (t0.dataprincipale IS NOT NULL) ELSE t0.rec_creato END  DESC

而不是

ORDER BY CASE WHEN (t0.dataprincipale IS NOT NULL) THEN t0.dataprincipale ELSE t0.rec_creato END  DESC

但我不明白我的代码哪里出了问题。

有什么建议吗? 谢谢

【问题讨论】:

    标签: java jpa-2.0 criteria-api


    【解决方案1】:

    如果您使用的是 EclipseLink 2.3.x 或更早版本,请尝试升级到最新版本。

    我已经用 2.3.x 测试了你的代码并且失败了,但是从 2.4.x 接缝可以正常工作。

    【讨论】:

      【解决方案2】:

      将表达式放在一个额外的列中,然后按该列排序。与 SQL 相同。

      【讨论】:

      • 在 Postrgres SQL 中我通常写 ORDER BY CASE ... THEN ... ELSE ... END ;) 你的意思是 SELECT t0.*, CASE WHEN (t0.dataprincipale IS NOT NULL) THEN t0.dataprincipale ELSE t0.rec_creato END AS orderby_data FROM Attribuzione t0 ORDER BY orderby_data 吗?我尝试在 Criteria API 中翻译它。这是我的第一种方法...谢谢
      • SQL 在历史上对 ORDER BY 列的表达能力有限。 JPA 通常会稍晚一些且不太完整地实现 SQL 方言。接近标准 SQL 仍有其优势。
      【解决方案3】:

      没办法。我担心这是一个 Eclipse 错误(Eclipse Persistence Services - 2.3.2.v20111125-r10461):(

      您知道 Eclipse 中的一个错误吗?

      代码

      CriteriaQuery<Tuple> cqt= cb.createTupleQuery();
      Root<Attribuzione> roott = cqt.from(Attribuzione.class);
      cqt.multiselect(cb.selectCase()
                  .when(cb.isNotNull(roott.get(Attribuzione_.dataprincipale)), roott.get(Attribuzione_.dataprincipale))
                  .otherwise(roott.get(Attribuzione_.recordcreato)), roott);
      cqt = cqt.where(cb.equal(roott.get(Attribuzione_.esecutoreprincipale), "pivamichela"));
      TypedQuery<Tuple> tq = em.createQuery(cqt);
      

      生成此 SQL 代码(与“order by”中的错误相同)

      SELECT CASE WHEN (dataprincipale IS NOT NULL) THEN (dataprincipale IS NOT NULL) ELSE rec_creato END , ID, dataletto, dataprincipale, esecutoreletto, esecutoreprincipale, evidenza, letto, principale, rec_creato, rec_creato_da, rec_modificato, rec_modificato_da, protocollo, ufficio FROM PROTOCOLLO.ATTRIBUZIONE WHERE (esecutoreprincipale = ?)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-10-20
        • 2012-05-30
        • 2018-10-16
        • 2012-02-21
        • 1970-01-01
        • 1970-01-01
        • 2014-08-30
        • 1970-01-01
        相关资源
        最近更新 更多