diff --git a/src/site/docbook/reference/common-patterns.xml b/src/site/docbook/reference/common-patterns.xml
index 9e3f132ed..754f7862a 100644
--- a/src/site/docbook/reference/common-patterns.xml
+++ b/src/site/docbook/reference/common-patterns.xml
@@ -195,22 +195,32 @@
the end of the file. This footer serves as a summarization of the file
or provides a checksum.
- For example, if a batch job is writing Trade records to a flat
- file, and there is a requirement that the total amount from all the
- Trades is placed in a footer, then the following ItemWriter
- implementation can be used:
+ For example, if a batch job is writing
+ Trade records to a flat file, and there is a
+ requirement that the total amount from all the
+ Trades is placed in a footer, then the following
+ ItemWriter implementation can be used:
public class TradeItemWriter implements ItemWriter<Trade>,
FlatFileFooterCallback {
private ItemWriter<Trade> delegate;
- private double totalAmount = 0.0;
+ private BigDecimal totalAmount = BigDecimal.ZERO;
public void write(List<? extends Trade> items) {
+ for (Trade trade : items) {
+ // There must be an amount to total
+ Assert.notNull(trade.getAmount());
+ }
+
delegate.write(items);
- for(Trade trade : items) {
- totalAmount += trade.getAmount();
+ }
+
+ @AfterWrite
+ public void updateTotalPrice(List<Trade> trades) {
+ for (Trade trade : trades) {
+ totalAmount = totalAmount.add(trade.getAmount());
}
}
@@ -226,9 +236,21 @@
amount from each Trade item written.
After the last Trade is processed, the framework
will call writeFooter, which will put that
- totalAmount into the file. In order for the method to be
- called, the TradeItemWriter must be wired into
- the FlatFileItemWriter as the
+ totalAmount into the file. Note that the
+ totalAmount is not updated in
+ the write method; it is updated in the
+ AfterWrite method. This is done to ensure that if
+ a skip occurs in the write method, that the
+ totalAmount will be left unchanged. The
+ write method also validates that the
+ amount on each Trade is not
+ null; this guarantees that no exceptions will be thrown by the
+ AfterWrite method.
+
+ In order for the writeFooter method to be
+ called, the TradeItemWriter (which implements
+ FlatFileFooterCallback) must be wired into the
+ FlatFileItemWriter as the
footerCallback:
<bean id="tradeItemWriter" class="..TradeItemWriter">
@@ -236,9 +258,9 @@
</bean>
<bean id="flatFileItemWriter" class="org.spr...FlatFileItemWriter">
- <property name="resource" ref="outputResource" />
- <property name="lineAggregator" ref="lineAggregator"/>
- <property name="footerCallback" ref="tradeItemWriter" />
+ <property name="resource" ref="outputResource" />
+ <property name="lineAggregator" ref="lineAggregator"/>
+ <property name="footerCallback" ref="tradeItemWriter" />
</bean>
The way that the TradeItemWriter has been
@@ -251,17 +273,17 @@
with the methods open and
update:
- private static final String TOTAL_AMOUNT_KEY = "total.amount";
+ private static final String TOTAL_AMOUNT_KEY = "total.amount";
- public void open(ExecutionContext executionContext) {
- if (executionContext.containsKey(TOTAL_AMOUNT_KEY) {
- totalAmount = executionContext.getDouble(TOTAL_AMOUNT_KEY);
- }
- }
+public void open(ExecutionContext executionContext) {
+ if (executionContext.containsKey(TOTAL_AMOUNT_KEY) {
+ totalAmount = (BigDecimal) executionContext.get(TOTAL_AMOUNT_KEY);
+ }
+}
- public void update(ExecutionContext executionContext) {
- executionContext.setDouble(TOTAL_AMOUNT_KEY, totalAmount);
- }
+public void update(ExecutionContext executionContext) {
+ executionContext.put(TOTAL_AMOUNT_KEY, totalAmount);
+}
The update method will store the most
current version of totalAmount to the
@@ -272,12 +294,6 @@
for processing, allowing the TradeItemWriter to
pick up on restart where it left off the previous time the
Step was executed.
-
- It should be noted that it is not always necessary to implement
- ItemStream. For example, if the
- ItemWriter is re-runnable, meaning that it
- maintains its own state in a transactional resource like a database,
- there is no need to maintain state within the writer itself.