代码之家  ›  专栏  ›  技术社区  ›  dfche

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

  •  0
  • dfche  · 技术社区  · 6 年前

    有没有办法在带有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
    弹簧防尘套1.4.2。释放
    休眠5.1.0。最终版本(与5.2.16最终版本一起复制)
    Oracle 11.2

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

    1 回复  |  直到 6 年前
        1
  •  0
  •   Alberto    6 年前

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

    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确认,正在工作