我有一个小的示例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。
/jobLauncher.html
主班
@EnableAutoConfiguration @ComponentScan public class Application { public static void main(String[] args) throws Exception { SpringApplication.run(Application.class, new String[]{ "date=" + System.currentTimeMillis() }); } }
Web服务类
@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批处理类
@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; } }
找到了问题。使用@EnableAutoConfigurationSpring Boot中的注释时,它将调用org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration类,该类将从’schema- mysql.sql’文件初始化数据库。
@EnableAutoConfiguration
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration
在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