java 63 lines · 9 steps

How a chunk-based CSV import job works in Spring

A Spring Batch job reads customers from CSV, cleans each record, and writes them to the database in fault-tolerant chunks.

Explained by highlit
1@Configuration
2@EnableBatchProcessing
3public class CustomerImportJobConfig {
4 
5 @Bean
6 public FlatFileItemReader<CustomerCsvRecord> customerReader() {
7 return new FlatFileItemReaderBuilder<CustomerCsvRecord>()
8 .name("customerReader")
9 .resource(new ClassPathResource("customers.csv"))
10 .linesToSkip(1)
11 .delimited()
12 .names("externalId", "firstName", "lastName", "email", "signupDate")
13 .fieldSetMapper(fieldSet -> new CustomerCsvRecord(
14 fieldSet.readString("externalId"),
15 fieldSet.readString("firstName"),
16 fieldSet.readString("lastName"),
17 fieldSet.readString("email"),
18 fieldSet.readDate("signupDate", "yyyy-MM-dd")))
19 .build();
20 }
21 
22 @Bean
23 public ItemProcessor<CustomerCsvRecord, Customer> customerProcessor() {
24 return record -> {
25 if (record.email() == null || record.email().isBlank()) {
26 return null;
27 }
28 Customer customer = new Customer();
29 customer.setExternalId(record.externalId());
30 customer.setName(record.firstName().trim() + " " + record.lastName().trim());
31 customer.setEmail(record.email().toLowerCase());
32 customer.setSignupDate(record.signupDate());
33 return customer;
34 };
35 }
36 
37 @Bean
38 public JdbcBatchItemWriter<Customer> customerWriter(DataSource dataSource) {
39 return new JdbcBatchItemWriterBuilder<Customer>()
40 .dataSource(dataSource)
41 .sql("INSERT INTO customers (external_id, name, email, signup_date) "
42 + "VALUES (:externalId, :name, :email, :signupDate)")
43 .beanMapped()
44 .build();
45 }
46 
47 @Bean
48 public Step importCustomersStep(JobRepository jobRepository,
49 PlatformTransactionManager txManager,
50 FlatFileItemReader<CustomerCsvRecord> customerReader,
51 ItemProcessor<CustomerCsvRecord, Customer> customerProcessor,
52 JdbcBatchItemWriter<Customer> customerWriter) {
53 return new StepBuilder("importCustomersStep", jobRepository)
54 .<CustomerCsvRecord, Customer>chunk(200, txManager)
55 .reader(customerReader)
56 .processor(customerProcessor)
57 .writer(customerWriter)
58 .faultTolerant()
59 .skip(FlatFileParseException.class)
60 .skipLimit(25)
61 .build();
62 }
63}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Spring Batch's reader-processor-writer triad cleanly separates parsing, transformation, and persistence into swappable beans.
  2. 2Chunk-oriented steps commit work in fixed-size batches inside a transaction, balancing throughput against memory and rollback scope.
  3. 3A processor returning null filters an item out, and fault tolerance lets bad rows be skipped without aborting the whole job.

Related explainers

Share this explainer

Here's the card — post it anywhere.

How a chunk-based CSV import job works in Spring — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code