EMMA Coverage Report (generated Fri Jan 30 13:20:29 EST 2009)
[all classes][org.springframework.batch.item.database]

COVERAGE SUMMARY FOR SOURCE FILE [BatchSqlUpdateItemWriter.java]

nameclass, %method, %block, %line, %
BatchSqlUpdateItemWriter.java100% (2/2)92%  (12/13)97%  (145/150)94%  (30.9/33)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class BatchSqlUpdateItemWriter100% (1/1)91%  (10/11)96%  (114/119)92%  (23.9/26)
setAssertUpdates (boolean): void 0%   (0/1)0%   (0/4)0%   (0/2)
<static initializer> 100% (1/1)94%  (17/18)94%  (0.9/1)
BatchSqlUpdateItemWriter (): void 100% (1/1)100% (6/6)100% (2/2)
afterPropertiesSet (): void 100% (1/1)100% (9/9)100% (3/3)
doClear (): void 100% (1/1)100% (1/1)100% (1/1)
doFlush (): void 100% (1/1)100% (66/66)100% (9/9)
doWrite (Object): void 100% (1/1)100% (1/1)100% (1/1)
getResourceKey (): String 100% (1/1)100% (2/2)100% (1/1)
setItemPreparedStatementSetter (ItemPreparedStatementSetter): void 100% (1/1)100% (4/4)100% (2/2)
setJdbcTemplate (JdbcOperations): void 100% (1/1)100% (4/4)100% (2/2)
setSql (String): void 100% (1/1)100% (4/4)100% (2/2)
     
class BatchSqlUpdateItemWriter$1100% (1/1)100% (2/2)100% (31/31)100% (7/7)
BatchSqlUpdateItemWriter$1 (BatchSqlUpdateItemWriter, List): void 100% (1/1)100% (9/9)100% (1/1)
doInPreparedStatement (PreparedStatement): Object 100% (1/1)100% (22/22)100% (6/6)

1/*
2 * Copyright 2006-2007 the original author or authors.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.springframework.batch.item.database;
17 
18import java.sql.PreparedStatement;
19import java.sql.SQLException;
20import java.util.ArrayList;
21import java.util.Iterator;
22import java.util.List;
23 
24import org.springframework.batch.item.ClearFailedException;
25import org.springframework.batch.item.ItemWriter;
26import org.springframework.batch.repeat.RepeatContext;
27import org.springframework.beans.factory.InitializingBean;
28import org.springframework.dao.DataAccessException;
29import org.springframework.dao.EmptyResultDataAccessException;
30import org.springframework.jdbc.core.JdbcOperations;
31import org.springframework.jdbc.core.PreparedStatementCallback;
32import org.springframework.util.Assert;
33 
34/**
35 * {@link ItemWriter} that uses the batching features from
36 * {@link PreparedStatement} if available and can take some rudimentary steps to
37 * locate a failure during a flush, and identify the items that failed. When one
38 * of those items is encountered again the batch is flushed aggressively so that
39 * the bad item is eventually identified and can be dealt with in isolation.<br/>
40 * 
41 * The user must provide an SQL query and a special callback
42 * {@link ItemPreparedStatementSetter}, which is responsible for mapping the
43 * item to a PreparedStatement.<br/>
44 * 
45 * It is expected that {@link #write(Object)} is called inside a transaction,
46 * and that {@link #flush()} is then subsequently called before the transaction
47 * commits, or {@link #clear()} before it rolls back.<br/>
48 * 
49 * The writer is thread safe after its properties are set (normal singleton
50 * behaviour), so it can be used to write in multiple concurrent transactions.
51 * Note, however, that the set of failed items is stored in a collection
52 * internally, and this collection is never cleared, so it is not a great idea
53 * to go on using the writer indefinitely. Normally it would be used for the
54 * duration of a batch job and then discarded.
55 * 
56 * @author Dave Syer
57 * 
58 */
59public class BatchSqlUpdateItemWriter extends AbstractTransactionalResourceItemWriter implements InitializingBean {
60 
61        /**
62         * Key for items processed in the current transaction {@link RepeatContext}.
63         */
64        private static final String ITEMS_PROCESSED = BatchSqlUpdateItemWriter.class.getName() + ".ITEMS_PROCESSED";
65 
66        private JdbcOperations jdbcTemplate;
67 
68        private ItemPreparedStatementSetter preparedStatementSetter;
69 
70        private String sql;
71 
72        private boolean assertUpdates = true;
73 
74        /**
75         * Public setter for the flag that determines whether an assertion is made
76         * that all items cause at least one row to be updated.
77         * @param assertUpdates the flag to set. Defaults to true;
78         */
79        public void setAssertUpdates(boolean assertUpdates) {
80                this.assertUpdates = assertUpdates;
81        }
82 
83        /**
84         * Public setter for the query string to execute on write. The parameters
85         * should correspond to those known to the
86         * {@link ItemPreparedStatementSetter}.
87         * @param sql the query to set
88         */
89        public void setSql(String sql) {
90                this.sql = sql;
91        }
92 
93        /**
94         * Public setter for the {@link ItemPreparedStatementSetter}.
95         * @param preparedStatementSetter the {@link ItemPreparedStatementSetter} to
96         * set
97         */
98        public void setItemPreparedStatementSetter(ItemPreparedStatementSetter preparedStatementSetter) {
99                this.preparedStatementSetter = preparedStatementSetter;
100        }
101 
102        /**
103         * Public setter for the {@link JdbcOperations}.
104         * @param jdbcTemplate the {@link JdbcOperations} to set
105         */
106        public void setJdbcTemplate(JdbcOperations jdbcTemplate) {
107                this.jdbcTemplate = jdbcTemplate;
108        }
109 
110        /**
111         * Check mandatory properties - there must be a delegate.
112         */
113        public void afterPropertiesSet() throws Exception {
114                Assert.notNull(jdbcTemplate, "BatchSqlUpdateItemWriter requires an data source.");
115                Assert.notNull(preparedStatementSetter, "BatchSqlUpdateItemWriter requires a ItemPreparedStatementSetter");
116        }
117 
118        /**
119         * Create and execute batch prepared statement.
120         * @throws EmptyResultDataAccessException if any of the items does not cause an update
121         */
122        protected void doFlush() throws EmptyResultDataAccessException {
123 
124                final List processed = new ArrayList(getProcessed());
125 
126                if (!processed.isEmpty()) {
127 
128                        int[] values = (int[]) jdbcTemplate.execute(sql, new PreparedStatementCallback() {
129                                public Object doInPreparedStatement(PreparedStatement ps) throws SQLException, DataAccessException {
130                                        for (Iterator iterator = processed.iterator(); iterator.hasNext();) {
131                                                Object item = (Object) iterator.next();
132                                                preparedStatementSetter.setValues(item, ps);
133                                                ps.addBatch();
134                                        }
135                                        return ps.executeBatch();
136                                }
137                        });
138 
139                        if (assertUpdates) {
140                                for (int i = 0; i < values.length; i++) {
141                                        int value = values[i];
142                                        if (value == 0) {
143                                                throw new EmptyResultDataAccessException("Item " + i + " of " + values.length
144                                                                + " did not update any rows: [" + processed.get(i) + "]", 1);
145                                        }
146                                }
147                        }
148 
149                }
150 
151        }
152 
153        protected String getResourceKey() {
154                return ITEMS_PROCESSED;
155        }
156 
157        /**
158         * No-op.
159         */
160        protected void doWrite(Object output) {
161        }
162 
163        /**
164         * No-op.
165         */
166        protected void doClear() throws ClearFailedException {
167        }
168 
169}

[all classes][org.springframework.batch.item.database]
EMMA 2.0.5312 (C) Vladimir Roubtsov