Spring Batch配置initialize-schema:always触发表已存在错误求助
Spring Batch 每日启动初始化Schema报错的解决办法
针对你用Kubernetes CronJob每日启动Spring Batch 4.3.6应用,配置spring.batch.jdbc.initialize-schema: always导致PostgreSQL报relation "batch_job_instance" already exists错误的问题,给你三个可行的解决思路:
1. 手动初始化Schema后改用never配置
- 先执行一次Spring Batch官方提供的PostgreSQL初始化脚本
org/springframework/batch/core/schema-postgresql.sql,在你的PostgreSQL数据库中创建好Batch所需的表。 - 之后把应用配置改成:
这样每次应用启动就不会再执行Schema初始化,自然不会报错。spring: batch: jdbc: initialize-schema: never
2. 修改初始化脚本,添加表存在判断
- 复制官方的
schema-postgresql.sql脚本,将所有CREATE TABLE语句改成CREATE TABLE IF NOT EXISTS(PostgreSQL支持该语法)。 - 在应用配置中指定使用自定义脚本:
这样每次执行脚本时,数据库会自动跳过已存在的表,不会抛出错误。spring: batch: jdbc: initialize-schema: always schema: classpath:custom-schema-postgresql.sql
3. 自定义初始化逻辑,按需执行Schema创建
- 继承
DefaultBatchConfigurer,重写初始化方法,只在表不存在时执行脚本:import org.springframework.batch.core.configuration.annotation.DefaultBatchConfigurer; import org.springframework.core.io.ClassPathResource; import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; import javax.sql.DataSource; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; public class CustomBatchConfigurer extends DefaultBatchConfigurer { private final DataSource dataSource; public CustomBatchConfigurer(DataSource dataSource) { this.dataSource = dataSource; } @Override protected void initializeSchema() throws Exception { if (!tableExists("batch_job_instance")) { ResourceDatabasePopulator populator = new ResourceDatabasePopulator(); populator.addScript(new ClassPathResource("org/springframework/batch/core/schema-postgresql.sql")); populator.execute(dataSource); } } private boolean tableExists(String tableName) throws SQLException { try (Connection connection = dataSource.getConnection()) { ResultSet resultSet = connection.getMetaData().getTables(null, null, tableName.toUpperCase(), null); return resultSet.next(); } } } - 然后在配置类中注册这个自定义Configurer,同时把
initialize-schema设为never,让自定义逻辑接管初始化:import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.sql.DataSource; @Configuration public class BatchConfig { @Bean public CustomBatchConfigurer customBatchConfigurer(DataSource dataSource) { return new CustomBatchConfigurer(dataSource); } }
内容的提问来源于stack exchange,提问作者Muchtar
相关产品推荐
相关产品推荐

