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

Spring Boot中JPA原生Query更新后LocalDateTime查询无结果问题

问题解决:Spring Boot JPA操作MS SQL时Update后Select查不到数据

核心原因:时间精度不匹配

MS SQL的时间类型(如datetime/datetime2)和Java LocalDateTime的精度存在差异:

  • datetime类型精度仅到3.33毫秒,存入时会自动截断Java端的纳秒级时间;
  • datetime2精度到100纳秒,但LocalDateTime.now()生成的是纳秒级时间,存入时仍会有微小截断。
    你用原始的纳秒级LocalDateTime参数查询,自然匹配不到数据库中已被截断的时间值。

解决方案

方案1:用数据库端生成时间(最可靠)

直接在Update语句中使用MS SQL的时间函数,避免客户端和数据库的精度差异:

// 修改Update方法,不用传参数,直接用数据库时间
@Modifying
@Transactional
@Query(value = "UPDATE xy SET ts = SYSDATETIME()", nativeQuery = true)
void update();

// 如果需要获取这个数据库生成的时间,可以改成返回值
@Modifying
@Transactional
@Query(value = "UPDATE xy SET ts = SYSDATETIME(); SELECT SYSDATETIME();", nativeQuery = true)
LocalDateTime updateAndGetTimestamp();

调用示例:

LocalDateTime dbTimestamp = repository.updateAndGetTimestamp();
List<List<String>> list = repository.select(dbTimestamp);

方案2:统一Java端时间精度

手动截断LocalDateTime到和数据库字段匹配的精度:

  • 若数据库用datetime(毫秒级):
LocalDateTime now = LocalDateTime.now().truncatedTo(ChronoUnit.MILLIS);
repository.update(now);
List<List<String>> list = repository.select(now);
  • 若数据库用datetime2(百纳秒级):
LocalDateTime now = LocalDateTime.now();
// 截断到100纳秒精度,匹配datetime2
now = now.withNano((now.getNano() / 100_000) * 100_000);
repository.update(now);
List<List<String>> list = repository.select(now);

方案3:检查事务有效性

如果Update和Select是同一类内部调用,Spring的AOP代理可能不会触发@Transactional注解,导致Update的修改未提交到数据库。解决方式:

  • 将Update和Select方法拆分到不同类;
  • 在调用这两个方法的外层Service方法上添加@Transactional:
@Service
public class XyService {
    @Autowired
    private XyRepository repo;

    @Transactional
    public List<List<String>> updateAndQuery() {
        LocalDateTime now = LocalDateTime.now().truncatedTo(ChronoUnit.MILLIS);
        repo.update(now);
        return repo.select(now);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 22:36:21