【问题标题】:HQL diff 2 date in daysHQL diff 2 日期(以天为单位)
【发布时间】:2015-11-04 08:38:20
【问题描述】:

我写正确的 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 cannot be cast to java.util.Date

我在哪里做错了? 数据库 Postgresql 9.4

【问题讨论】:

  • currentDate 的类型是什么?
  • dayscurrentDate的声明是什么?
  • 对不起,忘了写:java.util.Date currentDate = new java.util.Date(System.currentTimeMillis());整数天 = 100;

标签: java hibernate postgresql hql


【解决方案1】:

在 where 子句中将 (i.smeEnd - :currentDate) 转换为整数的托盘

(i.smeEnd - :currentDate) ::integer

或作为演员...

cast ((i.smeEnd - :currentDate) as integer)

如果我没记错的话,前段时间我的大学确实发生了类似的事情。 java 检查传递参数条件的东西,它检查“:currentDate) 但希望这会有所帮助

2015-11-06 编辑

抱歉,不能发表评论,但尊重点不够 :) 回答你的意见

"cast ((i.smeEnd - :currentDate) as integer) 和 EXTRACT(EPOCH FROM date_trunc('day', age(i.smeEnd, :currentDate))) / 60 / 60 / 24 有什么区别?两个变体正在工作”

您必须了解,两者都有效,因为查询语法不同。 java(hibernate?)查询解析器有点“智能”,预先检查查询是否正常,它在查询中找到带有2个参数“:currentDate)

如果您在 ":currentDate [here] ) 或 [here]

(- :currentDate + i.smeEnd )

该查询也可以工作

【讨论】:

  • "SELECT i, cast ((i.smeEnd - :currentDate) as integer) FROM IncidentsEntity i WHERE cast ((i.smeEnd - :currentDate) as integer)
【解决方案2】:

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

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

  • WHERE 中,只需做一些数学运算
    (i.smeEnd - :currentDate) &lt;= :days 变为 i.smeEnd &lt;= 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

【讨论】:

  • cast ((i.smeEnd - :currentDate) as integer) 和 EXTRACT(EPOCH FROM date_trunc('day', age(i.smeEnd, :currentDate))) / 60 / 60 有什么不同/ 24 ?两个变体正在工作。
  • @maks28rus 如果您可以使用CAST,请使用它(它是更简单的变体)。在我的设置中,我无法让强制转换为此工作(也许我们使用不同的 Hibernate 版本)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-02-15
  • 1970-01-01
  • 2011-04-19
  • 2015-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多