我写了正确的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
答案 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