【发布时间】:2018-10-05 12:35:02
【问题描述】:
有没有办法通过 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))
我已经尝试(解决方案找到 here 和 here)将查询更改为以下内容
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 一起转载)
甲骨文 11.2
UPD: 也许它不在规范中,但是使用上面的代码将最大/nvl 函数正确地从 JPQL 传递到 SQL。我尝试将greatest/nvl 包装在function 中,但仍不接受文字。
【问题讨论】:
-
JPA 规范在哪里定义了
greatest的 JPQL 函数?或nvl?答:不会 -
@DN1 我已将查询字符串替换为更严格的 JPQL,通过“函数”调用最大/nvl,但它不会改变任何内容。它仍然接受参数并为其生成相同的 SQL,同时为文字抛出
unexpected char: '{'错误。select t from TestEntity t where function('greatest', function('nvl', t.f1, {ts '1970-01-01 00:00:00.000000001'}), function('nvl', t.f2, {ts '1970-01-01 00:00:00.000000001'})) between :startChanges and :endChanges -
根据@987654323,我可以使用 JDBC 转义语法(您使用的大括号和“ts”)与我的 JPA 提供程序没有问题(恕我直言,您的语法使用是有效的) @ 可以尝试一个不带函数调用的简单查询,并使用 JDBC 转义语法来检查您的 JPA 提供程序是否首先正确处理它,然后添加 FUNCTIONs。
-
@DN1 我尝试了一个非常基本的查询,没有条件,但有文字。它会导致相同的错误,看起来 Hibernate 5.1.0 不支持时间戳文字,至少使用这种语法。这至少是早期版本的问题stackoverflow.com/questions/8386109/…
-
听起来你需要对它们提出错误