Spring Batch+JPA导入CSV至MySQL:RepositoryItemWriter无数据插入
解决Spring Batch导入大CSV到MySQL无数据写入问题
核心问题:Job未执行
你的配置文件中设置了spring.batch.job.enabled=false,这会禁用Spring Batch作业的自动启动。应用启动后仅会初始化上下文,但不会触发importJob执行,这是数据未写入的首要原因。
解决方式
临时启用自动执行
修改application.properties:spring.batch.job.enabled=true重启应用后,Job会自动执行。
手动触发Job(生产环境推荐)
在主类中注入JobLauncher和Job,手动控制作业执行时机:@SpringBootApplication public class MysqlImportBatchApplication { public static void main(String[] args) throws Exception { ConfigurableApplicationContext context = SpringApplication.run(MysqlImportBatchApplication.class, args); JobLauncher jobLauncher = context.getBean(JobLauncher.class); Job importJob = context.getBean("import", Job.class); jobLauncher.run(importJob, new JobParameters()); System.exit(SpringApplication.exit(context)); } }保持
spring.batch.job.enabled=false,避免不必要的自动执行。
其他潜在问题排查与修复
1. CSV读取配置校验
- 文件路径与权限:确认
D:\\StockEtablissement_utf8.csv文件存在且应用有读取权限。 - 跳过表头:如果CSV包含表头,需在
FlatFileItemReader中添加跳过配置,否则表头会被当作数据行解析导致映射失败:return new FlatFileItemReaderBuilder<EstablishmentEntity>() .name("establishmentItemReader") .resource(new FileSystemResource("D:\\StockEtablissement_utf8.csv")) .delimited() .names("siren", "nic", "siret", ...) .linesToSkip(1) // 跳过CSV第一行表头 .fieldSetMapper(new BeanWrapperFieldSetMapper<>() {{ setTargetType(EstablishmentEntity.class); }}) .build();
2. 事务管理器冲突
你手动配置了JpaTransactionManager,但Spring Boot默认会自动配置事务管理器,可能导致Step注入错误:
- 移除自定义的
JpaTransactionManager、entityManagerFactoryBean、datasource配置,直接使用Spring Boot自动生成的Bean即可。 - 若必须自定义事务管理器,需添加
@Primary标记主事务管理器,或在Step中明确指定Bean名称。
3. 大文件导入性能优化
针对8GB超大CSV,RepositoryItemWriter单条插入性能极低,建议改用批量写入:
@Bean public JdbcBatchItemWriter<EstablishmentEntity> jdbcWriter(DataSource dataSource) { return new JdbcBatchItemWriterBuilder<EstablishmentEntity>() .dataSource(dataSource) .sql("INSERT INTO establishments (siren, nic, siret) VALUES (:siren, :nic, :siret)") .beanMapped() .build(); }
同时调大chunk大小,减少事务提交次数:
return new StepBuilder("step1", jobRepository) .<EstablishmentEntity, EstablishmentEntity> chunk(1000, transactionManager) // 调整为1000条/批次 .reader(reader()) .processor(processor()) .writer(jdbcWriter(dataSource)) .listener(listener) .build();
4. 连接池参数优化
调整HikariCP参数适配大文件导入场景:
spring.datasource.hikari.maximum-pool-size=20 spring.datasource.hikari.connection-timeout=30000 spring.datasource.hikari.max-lifetime=1800000
验证步骤
- 查看日志中是否有
importJob()和step()的warn输出,确认Job/Step已初始化并执行。 - 检查
BatchReadListener的控制台输出,验证Reader是否正常读取数据。 - 开启
spring.jpa.show-sql=true,查看控制台是否有INSERT语句执行。 - 添加解析异常监听器捕获数据格式错误:
@Bean public Step step1(...) { return new StepBuilder("step1", jobRepository) // 其他配置 .listener(new FlatFileParseExceptionListener()) .build(); }
内容的提问来源于stack exchange,提问作者davidvera
相关产品推荐
相关产品推荐

