CompositeItemWriter and ClassifierCompositeItemWriter Patterns
Fast recall
Quick revision
Core answer
Classifier> to route each item to exactly one writer based on a property — use it when items split into categories (valid vs invalid, high-priority vs normal, region A vs region B). Both patterns let you keep the chunk-step transaction model while fan-out or splitting writes; both must implement ItemStream correctly so restart and ExecutionContext flow through the wrapped writers.Whether you can compose writers for fan-out and routing requirements without leaving the chunk-step transaction model
Using a custom `ItemWriter` that loops over items and calls services inline, losing chunk batching and transaction semantics
Discuss `ItemStream` propagation in composite writers, the `BackToBackPatternClassifier`, and the transaction boundary across multiple sinks (one TX manager per writer is incorrect)
Interview-ready guide
Interview answer
Spring Batch has two composite-writer patterns that cover almost every multi-destination requirement.
`CompositeItemWriter` — fan-out:
- Delegates each chunk to every wrapped writer in registration order
- Use when every item must reach multiple sinks (DB plus audit file plus Kafka)
- All writes share the step's transaction — a failure rolls back all destinations
- Implements
ItemStreamand propagatesopen/update/closeto wrapped writers
`ClassifierCompositeItemWriter` — routing:
- Uses a
Classifierto route each item to exactly one writer> - Use when items split into categories — valid vs invalid, region A vs region B
- Items destined for the same writer are batched into sub-chunks, preserving batching
ItemStreamdoes NOT propagate automatically; register destination writers via.stream(writer)on the step
Transaction subtlety:
- All writers enrolled in the JDBC
PlatformTransactionManagerparticipate in rollback - Kafka or REST writers do NOT — they commit immediately
- For atomicity across DB and Kafka, use the outbox pattern: write a row inside the chunk transaction, dispatch from a separate step
Pattern-matching classifier:
BackToBackPatternClassifiermaps property values (or regex) to destinations declaratively- Useful for region-based or category-based routing
Idempotency required:
- Failed chunks re-execute on restart
- Destinations must tolerate re-writes — UPSERT, idempotency keys, or downstream deduplication
In an interview I'd flag the mixed-transaction-manager pitfall — that's the production bug composite writers most often produce.
CompositeItemWriter and ClassifierCompositeItemWriter Patterns
Direct Answer
CompositeItemWriter delegates each chunk to every wrapped writer in order — use it when every item must be persisted to multiple sinks (DB plus audit file plus Kafka). ClassifierCompositeItemWriter uses a Classifier<T, ItemWriter<? super T>> to route each item to exactly one writer based on a property — use it when items split into categories (valid vs invalid, high-priority vs normal, region A vs region B). Both patterns let you keep the chunk-step transaction model while fan-out or splitting writes; both must implement ItemStream correctly so restart and ExecutionContext flow through the wrapped writers.
Common Mistakes & Pitfalls
Using a custom ItemWriter that loops over items and calls services inline, losing chunk batching and transaction semantics
Check your understanding
Answer these without looking back at the article.
- How does ItemStream propagation differ between CompositeItemWriter and ClassifierCompositeItemWriter?
- What happens to a Kafka publish when the chunk transaction rolls back, and how do you fix it?
- When would you prefer a routing step with a JobExecutionDecider over ClassifierCompositeItemWriter?
- How would you implement a composite writer that dynamically discovers destinations at runtime?
Related interview prep categories
1Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.