首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Spring Batch:无法使用不同的JobParameters启动作业,并且无法访问JobParameters

Spring Batch:无法使用不同的JobParameters启动作业,并且无法访问JobParameters
EN

Stack Overflow用户
提问于 2021-02-11 23:46:43
回答 1查看 54关注 0票数 0

我必须解决Spring Batch的问题。两者都与通过命令行传入的JobParameters有关。

第一期:

我正在使用Eclipse开发我的应用程序并对其进行测试。因此,我补充说

..。这些论点是:

代码语言:javascript
运行
复制
-ts=${current_date} -path="file.csv"

运行应用程序将抛出异常。例外情况是:

代码语言:javascript
运行
复制
Caused by: org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException: 
A job instance already exists and is complete for parameters={ts=20210211_1631, path=file.csv}.  
If you want to run this job again, change the parameters.

正如您所看到的,每次执行的JobParameters应该是不同的,因为其中一个参数是每分钟都在变化的时间戳。我看过这个问题

Spring Batch:使用不同的参数执行相同的作业

,但这里的解决方案是为每个作业执行设置一个新名称(例如

)。这个问题还有其他解决方案吗?我不想在每次执行作业时都为它创建一个“随机”名称。我的作业是这样实现的:

代码语言:javascript
运行
复制
@Bean(name = "inJob")
public Job inJob(JobRepository jobRepository) {
    return jobBuilderFactory.get("inJob")
            .repository(jobRepository)
            .incrementer(new RunIdIncrementer())
            .start(truncateTable())
            .next(loadCsv())
            .next(updateType())
            .build();
}

我使用JobRepository的自定义实现将元数据存储在不同的数据库模式中:

代码语言:javascript
运行
复制
@Override
public JobRepository createJobRepository() throws Exception {
    JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
    factory.setDataSource(dataSource);
    factory.setTransactionManager(transactionManager);
    factory.setTablePrefix("logging.BATCH_");
    return factory.getObject();
}

第二期:

我的第二个问题是访问JobParameters。上面的一个参数是我想在FlatFileItemReader中使用的文件路径:

代码语言:javascript
运行
复制
@Bean(name = "inReader")
@StepScope
public FlatFileItemReader inReader() {       
    FlatFileItemReader reader = new FlatFileItemReader();
    reader.setResource(new FileSystemResource(path));
    DefaultLineMapper lineMapper = new DefaultLineMapper<>();
    lineMapper.setFieldSetMapper(new CsvInfileFieldMapper());
    DelimitedLineTokenizer tokenizer = new DelimitedLineTokenizer();
    tokenizer.setDelimiter("|");
    tokenizer.setNames(ccn.names);
    lineMapper.setLineTokenizer(tokenizer);
    reader.setLineMapper(lineMapper);
    reader.setLinesToSkip(1);
    reader.open(new ExecutionContext());
    return reader;
}

为了从JobParameters获取路径,我使用了BeforeStep注释来加载JobParameters并将它们复制到局部变量上。不幸的是,这不起作用。该变量将为

执行失败,因为文件无法打开。

代码语言:javascript
运行
复制
private String path;

@BeforeStep
public void beforeStep(StepExecution stepExecution) {
    JobParameters jobParameters = stepExecution.getJobParameters();
    this.path = jobParameters.getString("path");
}

如何在我的阅读器中访问JobParameters?我想传入文件路径作为命令行参数,然后读取此文件。

EN

Stack Overflow用户

回答已采纳

发布于 2021-02-12 03:10:43

第一个问题:这个问题还有其他解决方案吗?

您的当前日期是每分钟解析一次,因此,如果您在该分钟内多次运行作业,则可能已经有一个具有相同参数的作业实例,因此出现了问题。你的

参数的精度应为秒(如果需要,也可以更小)。

第二个问题:如何在我的阅读器中访问JobParameters?我想传入文件路径作为命令行参数,然后读取此文件。

你不需要那个

方法。您可以在bean定义中后期绑定作业参数,如下所示:

代码语言:javascript
运行
复制
@Bean(name = "inReader")
@StepScope
public FlatFileItemReader inReader(@Value("#{jobParameters['path']}") String path) {       
    FlatFileItemReader reader = new FlatFileItemReader();
    reader.setResource(new FileSystemResource(path));
    // ...
    return reader;
}

这将在您的读取器定义中注入文件路径,如果您通过

作为作业参数,如下所示:

代码语言:javascript
运行
复制
java -jar myjob.jar path=/absolute/path/to/your/file

中解释了这一点。

作业和步骤属性的后期绑定

参考文档的一节。

票数 2
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66158021

复制
相关文章

相似问题

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