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

Spring Boot 3.2.0中使用JdbcTemplate将Java LocalDate持久化到Oracle DATE列时出现意外时间组件问题

Spring Boot 3.2.0中使用JdbcTemplate将Java LocalDate持久化到Oracle DATE列时出现意外时间组件问题

这个问题我刚好碰到过类似的情况,咱们来一步步拆解原因和解决办法:

问题根源分析

你遇到的情况本质上是Oracle JDBC驱动的行为变更导致的:

  • Spring Boot 3.2.0默认把ojdbc11升级到了23.3.0.23.09版本,这个版本的驱动在处理LocalDate到Oracle DATE类型的映射逻辑上做了调整——之前会默认给LocalDate附加午夜00:00:00的时间组件,现在改成了正午12:00:00。
  • Spring的JdbcTemplate本身并没有改变类型转换的逻辑,它只是委托底层的JDBC驱动来完成Java类型到数据库类型的映射,所以问题的核心在驱动版本的差异上。

可行的解决方案

根据你的需求,这里提供几种不同的解决思路,你可以根据实际场景选择:

1. 显式转换为带午夜时间的LocalDateTime

最直接的方式就是在代码里把LocalDate转换成LocalDateTime并明确指定时间为午夜,这样不管驱动怎么处理,最终写入数据库的都是00:00:00:

public void insert() {
    final String sql = "INSERT INTO EXAMPLE (EXAMPLE_DATE) VALUES (?)";
    // 把LocalDate转换成当天午夜的LocalDateTime
    LocalDateTime midnightDateTime = LocalDate.now().atStartOfDay();
    this.jdbcTemplate.update(sql, midnightDateTime);
}

2. 利用Oracle SQL函数截断时间

在插入的SQL语句中使用Oracle的TRUNC()函数,这个函数会自动把日期的时间部分截断到午夜,不管传入的时间是什么,最终存储的都是00:00:00:

public void insert() {
    // 使用TRUNC函数确保时间部分为午夜
    final String sql = "INSERT INTO EXAMPLE (EXAMPLE_DATE) VALUES (TRUNC(?))";
    this.jdbcTemplate.update(sql, LocalDate.now());
}

3. 自定义全局类型转换器

如果你的项目中有很多地方需要处理这种场景,可以注册一个自定义的类型转换器,统一处理LocalDate到数据库DATE类型的映射:

public void insert() {
    final String sql = "INSERT INTO EXAMPLE (EXAMPLE_DATE) VALUES (?)";
    this.jdbcTemplate.update(sql, new AbstractSqlTypeValue() {
        @Override
        protected Object createTypeValue(Connection con, int sqlType, String typeName) throws SQLException {
            // 手动转换为带午夜时间的Timestamp
            LocalDate localDate = LocalDate.now();
            return Timestamp.valueOf(localDate.atStartOfDay());
        }
    });
}

这种方式适合全局统一规范,避免重复代码。

4. 临时降级JDBC驱动版本

如果暂时不想修改代码,可以在项目的依赖配置中显式指定ojdbc11的版本为21.11.0.0,恢复到之前的行为:

  • Maven配置示例:
<dependency>
    <groupId>com.oracle.database.jdbc</groupId>
    <artifactId>ojdbc11</artifactId>
    <version>21.11.0.0</version>
</dependency>
  • Gradle配置示例:
implementation 'com.oracle.database.jdbc:ojdbc11:21.11.0.0'

不过这只是临时方案,建议还是优先适配新驱动的行为,避免后续版本升级再次出现类似问题。

备注:内容来源于stack exchange,提问作者Santiago Ordax

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.20 08:43:10