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
‹ swipe to step through ›
Walkthrough
Space play
←→ step
click any line
Three takeaways
- 1Spring Batch's reader-processor-writer triad cleanly separates parsing, transformation, and persistence into swappable beans.
- 2Chunk-oriented steps commit work in fixed-size batches inside a transaction, balancing throughput against memory and rollback scope.
- 3A processor returning null filters an item out, and fault tolerance lets bad rows be skipped without aborting the whole job.
Related explainers
java
@Configuration @EnableWebSecurity public class ResourceServerConfig {
Configuring a JWT resource server in Spring
oauth2
jwt
authorization
Intermediate
8 steps
java
@Configuration public class OrderConsumerConfig { @Bean
Wiring a resilient Kafka consumer in Spring
kafka
deserialization
error-handling
Intermediate
8 steps
java
@Configuration @EnableKafka public class KafkaErrorHandlingConfig {
Kafka retry and dead-letter handling in Spring
kafka
error-handling
retry
Intermediate
7 steps
java
@Controller @RequestMapping("/employees") public class EmployeeController {
Customizing form binding in a Spring MVC controller
data-binding
validation
type-conversion
Intermediate
9 steps
java
package com.example.config.condition; import org.springframework.context.annotation.Condition; import org.springframework.context.annotation.ConditionContext;
A custom @Conditional feature flag in Spring
conditional beans
feature flags
annotations
Intermediate
7 steps
java
public List<OrderSummary> streamRecentOrders(LocalDateTime since, Consumer<OrderSummary> handler) { String sql = """ SELECT id, customer_id, total_cents, status, created_at FROM orders
Streaming large JDBC result sets safely
jdbc
streaming
resource-management
Intermediate
7 steps
Share this explainer
Here's the card — post it anywhere.
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code
Embed this explainer
Drop the interactive walkthrough into a blog or docs. Views never cost a credit.
<iframe src="https://highlit.co/explainers/how-a-chunk-based-csv-import-job-works-in-spring-explained-java-4601/embed?autoplay=1" width="100%" height="520" loading="lazy" style="border:0"></iframe>
Autoplay is on by default — add ?autoplay=0 to start paused.