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

升级SpringBoot3/Hibernate6后,JPQL的current_timestamp无法填充Instant字段

问题原因

Spring Boot 3.0.2 搭配的 Hibernate 6 对 JPQL 的类型校验逻辑做了强化,current_timestamp 在 JPQL 中会被解析为 java.sql.Timestamp 类型,而你的实体类中 modifiedAt 字段是 java.time.Instant 类型,两者类型不匹配,导致启动时校验失败。

解决方案

方案一:JPQL 内强制类型转换

修改 Repository 中的查询语句,通过 CAST 将 current_timestamp 转换为 java.time.Instant 类型,既保留 JPQL 的跨数据库特性,又解决类型不匹配问题:

@Repository
public interface IngredientRepository extends CrudRepository<Ingredient, String> {
    @Modifying
    @Query("update Ingredient set active = false, modifiedAt = CAST(current_timestamp AS java.time.Instant) where id in :removedIds")
    int deactivate(@Param("removedIds") Collection<String> toBeRemoved);
}

方案二:传入 Instant 类型参数

把当前时间作为参数传入查询,避免在 JPQL 中直接使用数据库函数,这种方式更灵活,还能统一使用应用服务器时间而非数据库时间:

@Repository
public interface IngredientRepository extends CrudRepository<Ingredient, String> {
    @Modifying
    @Query("update Ingredient set active = false, modifiedAt = :modifiedAt where id in :removedIds")
    int deactivate(@Param("removedIds") Collection<String> toBeRemoved, @Param("modifiedAt") Instant modifiedAt);
}

调用该方法时传入 Instant.now() 即可完成赋值。

方案三:使用原生 SQL 查询(依赖数据库语法)

如果可以接受数据库特定语法,也可以使用原生 SQL,此时 Hibernate 会自动处理字段类型映射:

@Repository
public interface IngredientRepository extends CrudRepository<Ingredient, String> {
    @Modifying
    @Query(value = "update ingredient set active = false, modified_at = CURRENT_TIMESTAMP where id in :removedIds", nativeQuery = true)
    int deactivate(@Param("removedIds") Collection<String> toBeRemoved);
}

注意这里要使用数据库表的实际字段名(比如 modified_at,而非实体类的 modifiedAt)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 05:54:56