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

Spring Batch按日期排序时oracle.sql.TIMESTAMP序列化报错如何解决?

问题根因

  1. 你自定义的全局ObjectMapper不生效是因为Spring Batch内部处理执行上下文序列化的Jackson2ExecutionContextStringSerializer是单独初始化的,默认不会复用Spring容器里的@Primary ObjectMapper,所以你加的Oracle TIMESTAMP序列化规则根本没被Batch用到。
  2. 报错的本质是JdbcPagingItemReader做分页时,会把每页最后一条的排序键值(也就是你这里的MY_DT字段值)作为分页偏移量存到执行上下文里,而Oracle JDBC驱动默认返回的日期类型是oracle.sql.TIMESTAMP原生类型,Jackson没有内置的序列化支持,就会触发你看到的序列化失败错误。

解决方案推荐

方案1:修改JDBC连接参数(最省力)

直接在你的Oracle数据库连接URL或者连接属性里添加参数oracle.jdbc.J2EE13Compliant=true,这个参数会让Oracle驱动把原生的oracle.sql.TIMESTAMP自动转换成标准的java.sql.Timestamp返回,Jackson本身支持对标准JDK日期类型的序列化,不需要额外改代码。
示例连接配置:

spring.datasource.url=jdbc:oracle:thin:@//host:port/service?oracle.jdbc.J2EE13Compliant=true

方案2:显式配置Spring Batch的执行上下文序列化器(适合需要保留序列化自定义规则的场景)

你需要把自定义的序列化规则注册到Spring Batch专用的序列化器里,而不是只定义全局ObjectMapper:

@Configuration
@EnableBatchProcessing
public class BatchConfig extends DefaultBatchConfigurer {
    @Override
    protected ExecutionContextSerializer createExecutionContextSerializer() {
        ObjectMapper objectMapper = new ObjectMapper();
        // 注册你自己写的OracleTimestampSerializer
        SimpleModule simpleModule = new SimpleModule();
        simpleModule.addSerializer(oracle.sql.TIMESTAMP.class, new OracleTimestampSerializer());
        objectMapper.registerModule(simpleModule);
        // 其他你需要的ObjectMapper配置
        return new Jackson2ExecutionContextStringSerializer(objectMapper);
    }
}

注意:你之前写的序列化器里加的RuntimeException测试用的代码要记得删掉,否则会主动抛异常。另外建议你把序列化逻辑改成将oracle.sql.TIMESTAMP转成标准LocalDateTime后序列化,比写二进制兼容性更好,反序列化也更方便

方案3:关闭Reader的状态保存(适合不需要断点重启的一次性作业)

如果你的作业不需要支持失败后从断点重启,可以直接给JdbcPagingItemReader设置saveState=false,这样Reader就不会把分页偏移量存到执行上下文里,也就不会触发序列化流程,自然不会报错:

JdbcPagingItemReader<YourEntity> reader = new JdbcPagingItemReader<>();
reader.setSaveState(false);
// 其他reader配置

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 13:21:00