使用Hibernate的JPQL类型查询中的时间戳文字

时间:2018-04-25 06:28:02

标签: java hibernate jpa jpql

有没有办法在使用Hibernate的JPQL查询中使用时间戳文字?

有一个常量时间戳可供比较,应该放在JPQL查询中。 现在它以这种方式工作

TypedQuery<TestEntity> query = entityManager
.createQuery("select t from TestEntity t where greatest(nvl(t.f1, :nullDate), nvl(t.f2, :nullDate)) between :date1 and :date2")
.setParameter("date1", date1)
.setParameter("date2", date2)
.setParameter("nulllDate", LocalDateTime.of(1970, 1, 1, 0, 0, 0, 1))

我已尝试过(找到解决方案herehere)将查询更改为以下内容

select t from TestEntity t where greatest(nvl(t.f1, {ts '1970-01-01 00:00:00:000000001'}), nvl(t.f2, {ts '1970-01-01 00:00:00:000000001'})) between :startChanges and :endChanges

但在运行时出错

org.hibernate.QueryException: unexpected char: '{' [select t from TestEntity t where greatest(nvl(t.f1, {ts '1970-01-01 00:00:00:000000001'}), nvl(t.f2, {ts '1970-01-01 00:00:00:000000001'})) between :startChanges and :endChanges]

我的设置是
Java 8
JPA 2.1
Spring Boot 1.4.2.RELEASE
Hibernate 5.1.0.Final(也转载于5.2.16.Final)
Oracle 11.2

UPD:也许它不在规范上,但是使用上面的代码正确地将最大/ nvl函数从JPQL传递到SQL。我试图将greatest / nvl包裹在function中,但文字仍未被接受。

1 个答案:

答案 0 :(得分:0)

我已经在我的环境中准备了一个测试,这会返回结果:

Calendar calendar = Calendar.getInstance();
calendar.setTime(date1);
calendar.set(Calendar.HOUR, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);

date1 = calendar.getTime();

calendar.setTime(date2);
calendar.set(Calendar.HOUR, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);

date2 = calendar.getTime();

TypedQuery<TestEntity> query = entityManager
.createQuery("select t from TestEntity t where greatest(nvl(t.f1, TO_TIMESTAMP('1970-01-01 00:00:00,000000001', 'YYYY-MM-DD HH24:MI:SS,FF9')), nvl(t.f2, TO_TIMESTAMP('1970-01-01 00:00:00,000000001', 'YYYY-MM-DD HH24:MI:SS,FF9')) between :date1 and :date2")
.setParameter("date1", date1)
.setParameter("date2", date2);

我希望这是你正在寻找的。

编辑:修改后的查询以添加TO_TIMESTAMP功能。由@dfche确认它正在工作