You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot 3.1.11升级到3.2.5后Hibernate日期运算报错求助

问题原因及解决方案

根因

Spring Boot 3.2.5 配套的 Hibernate 6 对 JPQL 的类型检查变得更严格。之前版本中允许直接对日期类型做数值加减(比如current_date-60),但现在要求必须使用**时间量类型(TemporalAmount)**或标准日期函数来进行日期运算,否则就会抛出SemanticException错误。

等效实现方案

针对你的 Oracle 数据库场景,推荐使用 Hibernate 6 支持的DATEADD函数来替代直接的数值加减,该函数会自动转换为 Oracle 兼容的 SQL 语法。

示例1修复

原代码:

@Repository
interface APCheckRepository extends JpaRepository<APCheck, Long> {
    @Query("select abc from TestTable abc"
        + " WHERE abc.checkDate >= ORACLE_TRUNC(current_date-60)")
    List<TestTable> findSomething(); 
}

修复后:

@Repository
interface APCheckRepository extends JpaRepository<APCheck, Long> {
    @Query("select abc from TestTable abc"
        + " WHERE abc.checkDate >= ORACLE_TRUNC(DATEADD('day', -60, CURRENT_DATE))")
    List<TestTable> findSomething(); 
}

DATEADD('day', -60, CURRENT_DATE)等价于原逻辑中“当前日期减60天”的操作,Hibernate 会将其翻译为 Oracle 原生的CURRENT_DATE - 60语法。

示例2修复

原代码中的时间加减逻辑(如0.5/24代表30分钟)可以通过DATEADD指定更清晰的时间单位来实现:

原代码:

@Query("select d from TestTable2 d where "
        + "  d.dateOfService-(0.5/24) <= :dosTo " // dateOfService within 30 mins of dosTo
        + "  and d.dateOfService-(23/24) <= :dos " // dateOfService within 23 hours of dos
        + "  and d.dateOfServiceTo-(24.5/24) <= :dos " // dateOfServiceTo within 24 1/2 hours of dos
        + "order by"
        + "  d.quantity")
List<TestTable2> findSomething2( 
        @Param("dos") Date dos,
        @Param("dosTo") Date dosTo);

修复后:

@Query("select d from TestTable2 d where "
        + "  DATEADD('minute', -30, d.dateOfService) <= :dosTo " // dateOfService within 30 mins of dosTo
        + "  and DATEADD('hour', -23, d.dateOfService) <= :dos " // dateOfService within 23 hours of dos
        + "  and DATEADD('hour', -24.5, d.dateOfServiceTo) <= :dos " // dateOfServiceTo within 24 1/2 hours of dos
        + "order by"
        + "  d.quantity")
List<TestTable2> findSomething2( 
        @Param("dos") Date dos,
        @Param("dosTo") Date dosTo);

如果你更倾向于保留“天数分数”的写法,也可以用:

DATEADD('day', -(0.5/24), d.dateOfService) <= :dosTo

额外说明

  • 你的自定义方言无需额外修改,Hibernate 6 的 Oracle 方言已内置对DATEADD函数的支持,会自动转换为 Oracle 可识别的日期运算语法。
  • 如果需要使用数据库服务器时区的时间(而非 JVM 时区),可以将CURRENT_DATE替换为FUNCTION('SYSDATE'),比如:
    ORACLE_TRUNC(DATEADD('day', -60, FUNCTION('SYSDATE')))
    

内容的提问来源于stack exchange,提问作者coloradoman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 02:35:02