HQL diff 2 以天为单位的日期

HQL diff 2 date in days

我写对了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

tray to cast (i.smeEnd - :currentDate) to integer in where clause

(i.smeEnd - :currentDate) ::整数 <= :days

或演员...

cast ((i.smeEnd - :currentDate) as integer) <= :days

如果我没记错的话,不久前我的大学也发生过类似的事情。 java 检查传递的参数条件的东西,它检查“:currentDate)<=:days”从其他数据类型转换,预先检查这个条件并假设两个参数必须是忽略该括号的日期,无法记住细节。我很少和 java 一起工作,这也不是我的母语
但希望这会有所帮助

2015-11-06 编辑

抱歉,不能发表评论还没有足够的尊重点:) 回答您的评论

"What different between cast ((i.smeEnd - :currentDate) as integer) and EXTRACT(EPOCH FROM date_trunc('day', age(i.smeEnd, :currentDate))) / 60 / 60 / 24 ? Two variant are working"

你必须明白,两者都有效,因为查询语法不同。 java(hibernate?)查询解析器出现问题有点"smart",预检查查询是否正确,它在查询中发现一个条件有2个参数“:currentDate)<=:days”并失败了,因为它试图预先检查条件是否有效,不知道细节,当你有一些其他条件,不同的参数类型彼此相邻,逻辑用括号封装时,也会发生同样的问题。

如果您在“:currentDate [此处] ) 或 [此处] <= :days” 之间放置任何内容,该查询将对您有效,我敢打赌,如果您切换这两个值 (i.smeEnd - :currentDate) <= :days 至

(- :currentDate + i.smeEnd ) <= :days

该查询也有效

不幸的是,Hibernate 不能很好地处理 date/time 运算符(它通常不理解,它们可以 return 是什么类型)。在您的情况下,这意味着它将 (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