我有一个小样本Spring Batch应用程序,第一次启动时可以正常工作,但每当我关闭应用程序时重启jar我总是得到这个错误:
Caused by: org.springframework.dao.DuplicateKeyException: PreparedStatementCallback; SQL [INSERT into BATCH_JOB_INSTANCE(JOB_INSTANCE_ID, JOB_NAME, JOB_KEY, VERSION) values (?, ?, ?, ?)]; Duplicate entry '1' for key 1; nested exception is com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '1' for key 1
我不确定我的作业增量设置是否错误。但就像我说我可以启动它&然后使用Web服务URL /jobLauncher.html
,可以多次调用批处理过程。这只是在我关闭应用程序之后重启它,我收到此错误。它希望将id 1用于作业执行表,但是id 1已经存在于之前的运行中。
主要课程
@EnableAutoConfiguration
@ComponentScan
public class Application {
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, new String[]{ "date=" + System.currentTimeMillis() });
}
}
Webservice类
@Controller
public class JobLauncherController {
@Autowired
JobLauncher jobLauncher;
@Autowired
Job job;
@RequestMapping("/jobLauncher.html")
@ResponseBody
public String handle() throws Exception{
jobLauncher.run(job, new JobParametersBuilder().addString("date", System.currentTimeMillis() + "").toJobParameters());
return "Started the batch...";
}
}
Spring Batch类
@Configuration
@EnableBatchProcessing
public class SampleBatchApplication {
@Autowired
private JobBuilderFactory jobs;
@Autowired
private StepBuilderFactory steps;
@Bean
protected Tasklet tasklet() {
return new Tasklet() {
@Override
public RepeatStatus execute(StepContribution contribution,
ChunkContext context) {
return RepeatStatus.FINISHED;
}
};
}
@Bean
public Job job() throws Exception {
return this.jobs.get("job")
.incrementer(new RunIdIncrementer())
.flow(this.step1())
.end()
.build();
}
@Bean
protected Step step1() throws Exception {
return this.steps.get("step1").tasklet(this.tasklet()).build();
}
@Bean
public DataSource dataSource() {
BasicDataSource ds = new BasicDataSource();
try {
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUsername("test");
ds.setPassword("test");
ds.setUrl("jdbc:mysql://127.0.0.1:3306/spring-batch");
} catch (Exception e) {
e.printStackTrace();
}
return ds;
}
}
答案 0 :(得分:3)
发现了这个问题。使用Spring Boot中的@EnableAutoConfiguration
注释时,它将调用org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration
类,该类将从'schema-mysql.sql'文件初始化数据库。
在schema-mysql.sql文件中有一些代码可以重置批处理元表的序列ID,这就是我遇到重复键错误的原因:
INSERT INTO BATCH_STEP_EXECUTION_SEQ values(0);
INSERT INTO BATCH_JOB_EXECUTION_SEQ values(0);
INSERT INTO BATCH_JOB_SEQ values(0);
修复方法是单独构建Spring Batch表&然后将@EnableAutoConfiguration
注释更改为:
@EnableAutoConfiguration(exclude={BatchAutoConfiguration.class})
这样当应用程序启动时,它不会尝试初始化Spring Batch表。
要排除或自定义Spring Boot的其他组件的自动配置,您可以在此处找到一些文档:http://projects.spring.io/spring-boot/docs/spring-boot-autoconfigure/README.html
BatchAutoConfiguration代码: https://github.com/spring-projects/spring-boot/blob/master/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BatchAutoConfiguration.java
答案 1 :(得分:1)
我也遇到过类似的问题,也尝试过上述解决方案,但没有奏效。所以我用一种解决方法修复了它。
在为表 BATCH_JOB_INSTANCE 创建 Spring Batch 元数据架构时,为列 JOB_INSTANCE_ID 添加 AUTO_INCREMENT,它将解决您的问题。 >