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

Spring Boot执行MySQL删除48小时前数据的SQL查询报错问题

解决Spring Boot中删除48小时前数据的JPQL解析错误问题

问题原因

你遇到的错误是因为JPA默认把@Query里的语句当作JPQL(Java Persistence Query Language)解析,而JPQL不支持MySQL原生的INTERVAL 48 HOUR语法,所以解析器会抛出语法错误。

解决方法

方法一:使用原生MySQL查询(推荐)

直接让JPA执行原生SQL语句,只需在@Query注解里添加nativeQuery = true参数,同时别忘了加上@Modifying注解(因为这属于DML修改操作):

import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.transaction.annotation.Transactional;

public interface ScheduleRepository extends CrudRepository<Schedule, Long> {

    @Modifying
    @Transactional // 部分场景下需要显式开启事务
    @Query(value = "DELETE FROM schedule WHERE date_time < NOW() - INTERVAL 48 HOUR", nativeQuery = true)
    void deleteOldSchedules();
}

这种方式会把语句直接传给MySQL执行,和你在数据库客户端运行的效果完全一致,不会有语法解析问题。

方法二:使用JPQL兼容的日期计算

如果不想用原生SQL,可以用JPQL的语法实现相同逻辑,比如调用MySQL的DATE_SUB函数,或者使用JPQL自带的日期操作:

@Modifying
@Transactional
@Query("DELETE FROM Schedule s WHERE s.dateTime < FUNCTION('DATE_SUB', CURRENT_TIMESTAMP, FUNCTION('INTERVAL', 48, 'HOUR'))")
void deleteOldSchedules();

部分JPA实现(比如Hibernate)支持更简洁的写法:

@Modifying
@Transactional
@Query("DELETE FROM Schedule s WHERE s.dateTime < CURRENT_TIMESTAMP - INTERVAL '48' HOUR")
void deleteOldSchedules();

不过这种写法依赖具体的JPA实现,兼容性不如原生SQL稳定。

注意事项

  • 执行DELETE、UPDATE这类修改操作时,必须添加@Modifying注解,否则JPA会误认为是查询操作而报错。
  • 部分Spring Boot配置下,需要显式添加@Transactional注解开启事务,否则可能无法执行修改操作。

内容的提问来源于stack exchange,提问作者hilmi uğur

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 07:25:03