迁移至Spring Boot3后Hibernate extract函数失效,类型不匹配求助
问题与解决方案
迁移环境
- Spring Boot:3.0.1
- Java 17
- Hibernate:6.1.6
- Dialect:Oracle 12c
实体类代码
@Column(name = "ALARM_DT") @Temporal(TemporalType.DATE) private Calendar date;
原HQL语句
extract(day from (current_timestamp - alarm.date)) < 1
迁移后报错
org.hibernate.QueryException: Parameter 2 of function extract() has type TEMPORAL, but argument is of type java.time.Duration
解决方案
问题根源是Hibernate 6中,current_timestamp - alarm.date的计算结果为Duration类型,而extract(day from ...)要求参数是时间类型(TEMPORAL),直接调用就会触发类型不匹配的报错。以下是两种可行解决方式:
方式1:用datediff直接计算天数差(推荐)
Hibernate 6原生支持datediff函数,可直接算出两个日期的天数差值,语法清晰直观:
datediff(day, alarm.date, current_timestamp) < 1
该函数返回两个日期间的天数,直接和1比较就能满足原需求。
方式2:将Duration转换为天数(不推荐,可读性差)
如果一定要基于Duration处理,可以先提取总秒数再转换成天数:
extract(second from (current_timestamp - alarm.date)) / 86400 < 1
一天等于86400秒,用总秒数除以该数值得到天数后再做比较。但这种方式不如datediff直观,不推荐使用。
另外,建议将实体类中的Calendar替换为Java 8+的LocalDate,更适配Spring Boot 3和Hibernate 6的技术生态:
@Column(name = "ALARM_DT") private LocalDate date;
替换后无需再使用@Temporal注解,类型更简洁,Hibernate对java.time系列类型的支持也更完善。
内容的提问来源于stack exchange,提问作者user2212094
相关产品推荐
相关产品推荐

