首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Spring Batch WriterNotOpenException

Spring Batch WriterNotOpenException
EN

Stack Overflow用户
提问于 2017-03-27 18:07:50
回答 2查看 2.8K关注 0票数 1

我已经创建了一个简单的单步Spring批处理作业,它从DB读取项目,处理它们,并将结果写入csv。在运行时,我最终得到一个

代码语言:javascript
复制
org.springframework.batch.item.WriterNotOpenException: Writer must be open before it can be written to

相关代码:

代码语言:javascript
复制
@Configuration
@EnableBatchProcessing
@EnableAutoConfiguration
public class CleanEmailJob {

@Autowired
private JobBuilderFactory jobBuilderFactory;

@Autowired
private StepBuilderFactory stepBuilderFactory;

@Autowired
public DataSource dataSource;

@Bean
public ResourcelessTransactionManager transactionManager() {
    return new ResourcelessTransactionManager();
}

@Bean
public MapJobRepositoryFactoryBean mapJobRepositoryFactory(ResourcelessTransactionManager txManager)
        throws Exception {
    MapJobRepositoryFactoryBean factory = new MapJobRepositoryFactoryBean(txManager);
    factory.afterPropertiesSet();
    return factory;
}

@Bean
public JobRepository jobRepository(MapJobRepositoryFactoryBean factory) throws Exception {
    return factory.getObject();
}

@Bean
public JobExplorer jobExplorer(MapJobRepositoryFactoryBean factory) {
    return new SimpleJobExplorer(factory.getJobInstanceDao(), factory.getJobExecutionDao(),
            factory.getStepExecutionDao(), factory.getExecutionContextDao());
}

@Bean
public SimpleJobLauncher jobLauncher(JobRepository jobRepository) {
    SimpleJobLauncher launcher = new SimpleJobLauncher();
    launcher.setJobRepository(jobRepository);
    return launcher;
}


@Bean
public Job cleanEmailAddressesJob() throws Exception {
    return jobBuilderFactory.get("cleanEmailAddresses")
            .incrementer(new RunIdIncrementer())
            .start(processEmailAddresses())
            .build();
}

@Bean
public Step processEmailAddresses() throws UnexpectedInputException, ParseException, Exception {
    return stepBuilderFactory.get("processAffiliates")
            .<AffiliateEmailAddress, VerifiedAffiliateEmailAddress> chunk(10)
            .reader(reader())
            .processor(processor())     
            .writer(report())
            .build();
}

@Bean
public ItemWriter<VerifiedAffiliateEmailAddress> report(){
    FlatFileItemWriter<VerifiedAffiliateEmailAddress> reportWriter = new FlatFileItemWriter<VerifiedAffiliateEmailAddress>();
    reportWriter.setResource(new ClassPathResource("report.csv"));
    DelimitedLineAggregator<VerifiedAffiliateEmailAddress> delLineAgg = new DelimitedLineAggregator<VerifiedAffiliateEmailAddress>();
    delLineAgg.setDelimiter(",");
    BeanWrapperFieldExtractor<VerifiedAffiliateEmailAddress> fieldExtractor = new BeanWrapperFieldExtractor<VerifiedAffiliateEmailAddress>();
    fieldExtractor.setNames(new String[] {"uniekNr", "reason"});
    delLineAgg.setFieldExtractor(fieldExtractor);
    reportWriter.setLineAggregator(delLineAgg);
    reportWriter.setShouldDeleteIfExists(true);
    return reportWriter;
}

正如文档中所描述的,我希望生命周期事件(打开、关闭)自动得到处理,因为我是在单线程和单写入器作业中?

EN

回答 2

Stack Overflow用户

发布于 2017-03-27 23:10:06

为了详细说明留下的注释,Spring Batch将在找到任何ItemStream实现时自动注册它们,以便在步骤开始时自动打开它们。当使用java config时,Spring只知道返回类型是什么。由于您返回的是ItemReader,我们不知道您的实现是否也实现了ItemStream。当使用java config时,我通常建议返回已知的实现(而不是接口)。这使得Spring能够充分反思它。所以在这个例子中,返回FlatFileItemReader而不是ItemReader可以解决这个问题。

票数 4
EN

Stack Overflow用户

发布于 2017-03-27 18:52:14

最后,结果是Spring Dev工具干扰了我的批处理应用程序。report.csv在我的类路径中,当写入报告文件时,Spring Dev Tools检测到我的类路径中的更改,并触发应用程序的重新加载,从而导致report.csv资源被关闭……

代码语言:javascript
复制
spring.devtools.restart.enabled=false

在我的application.properties中让它再次工作

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43043554

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档