HQL差异2天数

时间:2015-11-04 08:38:21

标签: java hibernate postgresql hql

我写了正确的SQL查询:

SELECT i, (i.sme_end - '2015-09-10') 
FROM Incidents i 
WHERE (i.sme_end - '2015-09-10') <= 100 
ORDER BY ('2015-09-10' - i.sme_end)

但是当我在HQL上重写这个查询时:

java.util.Date currentDate = new java.util.Date(System.currentTimeMillis());
int days = 100;
session.createQuery("SELECT i, (i.smeEnd - :currentDate) "+
                "FROM IncidentsEntity i " +
                "WHERE (i.smeEnd - :currentDate) <= :days " +
                "ORDER BY (i.smeEnd - :currentDate)")
                .setParameter("days", days)
                .setParameter("currentDate", currentDate);

我得到ClassCastException:java.lang.Integer无法强制转换为java.util.Date

我哪里弄错了? 数据库Postgresql 9.4

2 个答案:

答案 0 :(得分:2)

托盘将(i.smeEnd - :currentDate)转换为where子句

中的整数

(i.smeEnd - :currentDate):: integer&lt; =:days

或作为演员...

施放((i.smeEnd - :currentDate)为整数)&lt; =:days

如果我没错,不久前我的大学也发生过类似的事情。用java检查传递参数条件的东西,它检查来自其他数据类型的“:currentDate”&lt; =:days“转换,预先检查这个条件并假设两个参数必须是忽略该括号的日期,不能记住细节。我很少使用java,这也不是我的家乡语言 但希望这有帮助

编辑2015-11-06

抱歉,不能评论但还不够尊重:) 回答你的屁股

“施放((i.smeEnd - :currentDate)为整数)和EXTRACT(EPOCH FROM date_trunc('day',age(i.smeEnd,:currentDate)))/ 60/60/24之间有什么不同?变体正在运作“

你必须明白,两者都有效,因为查询语法不同。 问题发生在java(hibernate?)查询解析器有点“智能”,预先检查查询是否正常,它在查询中找到一个条件,其中包含2个参数“:currentDate)&lt; =:days”并在其中失败,因为它试图预先检查条件是否有效,不知道细节,当你有一些其他条件与不同参数类型相邻时,可能会出现同样的问题,这些条件用括号括起来。

如果你在“:currentDate [here]”或[here]&lt; =:days“之间放置任何查询对你有用的东西,我打赌如果你切换这两个值  (i.smeEnd - :currentDate)&lt; =:days 到

( - :currentDate + i.smeEnd)&lt; =:days

该查询也可以使用

答案 1 :(得分:2)

不幸的是,Hibernate不能很好地处理日期/时间操作符(它通常不明白,它们可以返回什么类型)。在您的情况下,这意味着它将(i.smeEnd - :currentDate)表达式视为timestamp

要克服此限制,您可以通过以下方式调整HQL:

  • WHERE中,只需做一些数学计算 (i.smeEnd - :currentDate) <= :days因为i.smeEnd <= DATE(:currentDate) + :days {注意:currentDate绑定为timestamp,而不是date
  • ORDER BY中,只需删除常量部分(因为这根本不会影响排序)
    (i.smeEnd - :currentDate)成为i.smeEnd
  • SELECT中,那个人不会那么明显。如果您使用PostgreSQL81Dialect(或某些方言,扩展了该方言),HQL将理解age功能,因此
    (i.smeEnd - :currentDate)因为 EXTRACT(EPOCH FROM date_trunc('day', age(i.smeEnd, :currentDate))) / 60 / 60 / 24

整个查询:

SELECT i, EXTRACT(EPOCH FROM date_trunc('day', age(i.smeEnd, :currentDate))) / 60 / 60 / 24
FROM IncidentsEntity i
WHERE i.smeEnd <= (DATE(:currentDate) + :days)
ORDER BY i.smeEnd