Spring Batch-无法反序列化执行上下文-OffsetDateTime-无法反序列化

我正在尝试创建一个具有多个步骤的Spring Batch作业,并逐步传递对象。 为此,我使用从步骤到工作环境提升的ExecutionContext。 初次运行时,没有问题数据从一步到步都正确

在下次运行时,出现错误: “无法反序列化执行上下文”原因:com.fasterxml.jackson.databind.exc.InvalidDefinitionException:无法构造java.time.OffsetDateTime的实例(不存在创建者,如默认构造一样):无法从Object值反序列化(否基于委托人或财产的创建者)

我像这样在ItemWriter中编写上下文:

@Override
public void write(List<? extends Employee> items) throws Exception {
    ExecutionContext stepContext = this.stepExecution.getExecutionContext();
    List<Employee> e = new ArrayList<Employee>();
    e.addAll(items);
    stepContext.put("someKey",e);
}

然后使用:

在ItemReader中读取它(从另一步骤开始)
@BeforeStep
public void retrieveInterstepData(StepExecution stepExecution) {
    JobExecution jobExecution = stepExecution.getJobExecution();
    ExecutionContext jobContext = jobExecution.getExecutionContext();
    this.someObject = (List<Employee>) jobContext.get("someKey");
}

我检查spring数据库上下文,并且我的日期(LocalDate,OffsetDateTime等)存储为:

"LocalDate": {
    "year": 2019,"month": "OCTOber","dayOfMonth": 30,"monthValue": 10,"era": ["java.time.chrono.IsoEra","CE"],"dayOfWeek": "WEDnesDAY","dayOfYear": 303,"leapYear": false,"chronology": {
        "id": "ISO","calendarType": "iso8601"
    }
}
"OffsetDateTime": {
    "offset": {
        "totalSeconds": 0,"id": "Z","rules": {
            "fixedOffset": true,"transitionRules": ["java.util.Collections$unmodifiableRandomaccessList",[]],"transitions": ["java.util.Collections$unmodifiableRandomaccessList",[]]
        }
    },"year": 2019,"dayOfMonth": 28,"hour": 13,"minute": 42,"nano": 511651000,"second": 36,"dayOfWeek": "MONDAY","dayOfYear": 301
}

我想这样存储它是杰克逊的选择(我什么也没有定制) 但似乎杰克逊在下次运行时无法读取其自己的格式?!

我的存根是通过swagger的“ swagger-codegen-maven-plugin”和configOptions / datelibrary = java8生成的,因此我无法更改它们。

我尝试添加

<dependency>
    <groupId>com.fasterxml.jackson.datatype</groupId>
    <artifactId>jackson-datatype-jsr310</artifactId> 
</dependency>

还有

@PostConstruct
public void init() {
    objectMapper.registerModule(new JavaTimeModule());
    objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
}

在@SpringBootApplication中 没有变化

有什么想法吗?是将日期更简单地存储为“ 2019-11-04”,还是让jackson读取其自己的格式?

buguizebinggan 回答:Spring Batch-无法反序列化执行上下文-OffsetDateTime-无法反序列化

您的对象映射器应在作业存储库使用的Jackson2ExecutionContextStringSerializer上进行设置。您可以扩展DefaultBatchConfigurer并覆盖createJobRepository

@Bean
public JobRepository createJobRepository() throws Exception {
    ObjectMapper objectMapper = new ObjectMapper().registerModule(new JavaTimeModule());
    objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);

    Jackson2ExecutionContextStringSerializer defaultSerializer = new Jackson2ExecutionContextStringSerializer();
    defaultSerializer.setObjectMapper(objectMapper);

    JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
    factory.setDataSource(dataSource);
    factory.setTransactionManager(transactionManager);
    factory.setSerializer(defaultSerializer);
    factory.afterPropertiesSet();
    return factory.getObject();
}
,

编辑: 不好,我只是看到我有

@Bean
    public BatchConfigurer batchConfigurer(@Qualifier("batchDataSource") DataSource dataSource) {
    return new DefaultBatchConfigurer(dataSource);
}

提供2个batchConfigurer来启动。 谢谢!

原始:

谢谢,这似乎很有希望。 但是我找不到在哪个类上扩展和使用它的地方。

我有一个批处理类配置:

@Configuration
@EnableConfigurationProperties(BatchProperties.class)
public class BatchDatabaseConfiguration {

    @Value("${spring.datasource.driver-class-name}")
    private String driverClassName;
    @Value("${spring.datasource.url}")
    private String dbURL;

    @Bean("batchDataSource")
    public DataSource batchDataSource() {
    final DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setDriverClassName(driverClassName);
    dataSource.setUrl(dbURL);
    return dataSource;
    }

    @Bean
    public BatchConfigurer batchConfigurer(@Qualifier("batchDataSource") DataSource dataSource) {
    return new DefaultBatchConfigurer(dataSource);
    }

    @Bean(name = "batchTransactionManager")
    public PlatformTransactionManager batchTransactionManager(@Qualifier("batchDataSource") DataSource dataSource) {
    DataSourceTransactionManager tm = new DataSourceTransactionManager();
    tm.setDataSource(dataSource);
    return tm;
    }
}

还有一个具有Job定义的类:

@Configuration
@EnableBatchProcessing
public class ExtractionJobConfiguration {
    @Autowired
    private JobBuilderFactory jobBuilderFactory;

    @Autowired
    private StepBuilderFactory stepBuilderFactory;

    @Bean
    public Job creationJob() {
        ...
    }
    [...]
}

主要:

@EntityScan(basePackages = { "..." })
@SpringBootApplication
@EnableAsync
public class App {
public static void main(String[] args) {
    ApplicationContext ctx = SpringApplication.run(App.class,args);
}

您怎么看? 我还读到Spring Batch 4.2.0+允许在Jackson2ExecutionContextStringSerializer(https://jira.spring.io/browse/BATCH-2828)中自定义ObjectMapper。 那是你的建议吗? (我找不到其他信息)

本文链接:https://www.f2er.com/3165622.html

大家都在问