You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Batch的JdbcBatchItemWriter无法写入MariaDB数据库求助

Spring Batch中JdbcBatchItemWriter无法写入MariaDB的问题

问题现象

  • 系统可自动创建数据库表,说明数据库连接正常
  • 使用内存数据库时能成功写入数据,切换到MariaDB后数据无法写入
  • 日志无报错信息,但Spring Batch任务未启动执行

相关配置代码

DataSourceConfig.java

@Configuration
public class DataSourceConfig {

    @Bean
    @ConfigurationProperties("spring.datasource")
    public DataSource appDataSource() {
        DataSourceBuilder builder = DataSourceBuilder.create();
        builder.driverClassName("org.mariadb.jdbc.Driver");
        builder.url("jdbc:mariadb://localhost:3306/people");
        builder.username("user");
        builder.password("pwd");
        return builder.build();
    }
}

BatchConfiguration.java

@Configuration
public class BatchConfiguration {

    // tag::readerwriterprocessor[]
    @Autowired
    private DataSource dataSource;

    @Autowired
    private EntityManagerFactory entityManagerFactory;

    @Bean
    public JpaTransactionManager transactionManager() {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(entityManagerFactory);
        return transactionManager;
    }

    @Bean
    public FlatFileItemReader<Person> reader() {
        return new FlatFileItemReaderBuilder<Person>()
            .name("personItemReader")
            .resource(new ClassPathResource("sample-data.csv"))
            .delimited()
            .names(new String[]{"firstName", "lastName"})
            .fieldSetMapper(new BeanWrapperFieldSetMapper<Person>() {{
                setTargetType(Person.class);
            }})
            .build();
    }

    @Bean
    public PersonItemProcessor processor() {
        return new PersonItemProcessor();
    }

    @Bean
    public JdbcBatchItemWriter<People> writer() {
        JdbcBatchItemWriter<People> writer = new JdbcBatchItemWriter<>();
        writer.setDataSource(dataSource);
        writer.setSql("INSERT INTO people (first_name, last_name) VALUES (?, ?)");
        writer.setItemPreparedStatementSetter((item, ps) -> {
            ps.setString(1, item.getFirstName());
            ps.setString(2, item.getLastName());

            // Log the item being processed
            System.out.println("Processing item: " + item);
        });
        return writer;
    }


    // end::readerwriterprocessor[]

    // tag::jobstep[]
    @Bean
    public Job importUserJob(JobRepository jobRepository,
            JobCompletionNotificationListener listener, Step step1) {
        return new JobBuilder("importUserJob", jobRepository)
            .incrementer(new RunIdIncrementer())
            .listener(listener)
            .flow(step1)
            .end()
            .build();
    }

    @Bean
    public Step step1(JobRepository jobRepository,
                      JpaTransactionManager transactionManager, JdbcBatchItemWriter<People> writer) {
        return new StepBuilder("step1", jobRepository)
            .<Person, People> chunk(10, transactionManager)
            .reader(reader())
            .processor(processor())
            .writer(writer)
            .build();
    }
    // end::jobstep[]
}

BatchProcessingApplication.java

@SpringBootApplication
@EnableBatchProcessing(dataSourceRef ="appDataSource")
public class BatchProcessingApplication {

    public static void main(String[] args) throws Exception {
        SpringApplication.run(BatchProcessingApplication.class, args);
    }
}

Pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.1.0</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>batch-processing-complete</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>batch-processing-complete</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-batch</artifactId>
        </dependency>
        <dependency>
            <groupId>org.hsqldb</groupId>
            <artifactId>hsqldb</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.mariadb.jdbc</groupId>
            <artifactId>mariadb-java-client</artifactId>
            <version>3.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

排查与解决建议

1. 开启Batch任务自动执行

Spring Boot默认不会自动启动Batch任务,需添加配置:
在application.properties中加入:

spring.batch.job.enabled=true

或在主类中手动触发任务:

@SpringBootApplication
@EnableBatchProcessing(dataSourceRef ="appDataSource")
public class BatchProcessingApplication {

    public static void main(String[] args) throws Exception {
        SpringApplication.run(BatchProcessingApplication.class, args);
    }

    @Bean
    public CommandLineRunner runJob(JobLauncher jobLauncher, Job importUserJob) {
        return args -> {
            JobParameters jobParameters = new JobParametersBuilder()
                    .addLong("time", System.currentTimeMillis())
                    .toJobParameters();
            jobLauncher.run(importUserJob, jobParameters);
        };
    }
}

2. 调整事务管理器匹配度

当前使用JpaTransactionManager,但JdbcBatchItemWriter基于JDBC,建议改用DataSourceTransactionManager:

@Bean
public DataSourceTransactionManager transactionManager() {
    return new DataSourceTransactionManager(dataSource);
}

同时修改Step定义中的事务管理器引用。

3. 校验数据类型与映射

确认Person、People类的字段类型与数据库表字段一致,尤其是firstName、lastName是否为String类型。

4. 开启详细日志排查

在application.properties中添加日志配置,查看Batch执行细节:

logging.level.org.springframework.batch=DEBUG
logging.level.org.springframework.jdbc=DEBUG

5. 验证数据库权限

确认数据库用户user拥有people表的INSERT权限,可手动执行插入语句测试。

6. 规范JdbcBatchItemWriter构建方式

使用JdbcBatchItemWriterBuilder构建,避免遗漏初始化步骤,同时简化参数设置:

@Bean
public JdbcBatchItemWriter<People> writer() {
    return new JdbcBatchItemWriterBuilder<People>()
            .dataSource(dataSource)
            .sql("INSERT INTO people (first_name, last_name) VALUES (:firstName, :lastName)")
            .beanMapped()
            .build();
}

内容的提问来源于stack exchange,提问作者Buddhima Chamaranga

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 04:57:02