2014-02-05 34 views
6

我必须在数小时内获得当前日期与存储在数据库中的日期之间的差异。在PostgreSQL里,我能够使用以下查询做到这一点:如何使用HQL获取小时数的日期差异

SELECT storage_time, extract(epoch from (localtimestamp - storage_time))/3600 as diff_hour FROM some_table; 

这让我在小时日期之间的差值:

 storage_time  |  diff_hour  
-------------------------+------------------- 
2014-02-03 19:37:39.481 | 44.4788805811111 
2014-02-03 19:40:28.201 | 44.4320139144444 
2014-01-29 18:25:12.828 | 165.686284192222 
2014-02-03 19:25:56.861 | 44.6740528033333 
2014-02-05 15:53:38.178 | 0.212575858888889 
2014-01-30 15:53:38.61 | 144.212455858889 

现在,我面对的困难将它移植到Hibernate查询语言。我尝试了很多变化,但我无法从日期差异中获得时代。这肯定是不行的:

"FROM SomeEntity " + 
"WHERE someAttribute = :attr " + 
"AND epoch(localtimestamp - deviceInfo.storageTime)/3600 > :threshold_hour"; 

当我运行此命令时,我得到以下异常:

org.hibernate.exception.SQLGrammarException: could not extract ResultSet 
    at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2102) 
    at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1835) 
    at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257) 
    at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:500) 
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:388) 
    at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:273) 
    at org.apache.commons.dbcp.DelegatingPreparedStatement.executeQuery(DelegatingPreparedStatement.java:93) 
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.extract(ResultSetReturnImpl.java:56) 
    at org.hibernate.loader.Loader.getResultSet(Loader.java:2040) 
    at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1837) 
    at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1816) 
    at org.hibernate.loader.Loader.doQuery(Loader.java:900) 
    at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:342) 
    at org.hibernate.loader.Loader.doList(Loader.java:2526) 
    at org.hibernate.loader.Loader.doList(Loader.java:2512) 
    at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2342) 
    at org.hibernate.loader.Loader.list(Loader.java:2337) 
    at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:495) 
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:357) 
    at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:195) 
    at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1275) 
    at org.hibernate.internal.QueryImpl.list(QueryImpl.java:101) 

我跑这样的查询:

Query query = sessionFactory.getCurrentSession() 
        .getNamedQuery(GET_NON_EXPIRED_ENTITY) 
        .setString("attr", attr) 
        .setInteger("threshold_hour", thresholdHour); 

List<SomeEntity> instances = query.list(); 

的例外是在即将到来第二行,当我打电话list()

但是,当我将epoch()函数更改为day()时,在hibernate查询中,它无一例外地运行,但当然会产生意外的结果。

有没有什么办法可以在HQL中获得相同的PostgreSQL查询行为?

+0

我试图做这样的事情前一段时间我似乎记住并放弃。据我记得HQL没有API来做这样的事情 - 你需要诉诸本机SQL ... –

+0

@BoristheSpider :(:(真的很伤心:) :( –

+0

也许一些hibernate的大师会来,提示一些聪明的HQL结构,总有希望! –

回答

0

你可以尝试

"AND DATEDIFF('hour',deviceInfo.storageTime, localtimestamp) > :threshold_hour"; 
1
  1. HQL supports提取物(... FROM ...)功能,和EPOCH关键字,尽管它不是在documentstion提及。
  2. HQL还支持无参数LOCALTIMESTAMP函数(适用于Postgres和MySQL方言)。这其实也不是在文档,但我发现它在源(link1link2

因此,需要HQL查询:

FROM SomeEntity p 
WHERE EXTRACT(EPOCH FROM (LOCALTIMESTAMP-p.storageTime))/3600 > :threshold