EMMA Coverage Report (generated Thu Jan 24 13:37:04 CST 2013)
[all classes][org.springframework.batch.item.database]

COVERAGE SUMMARY FOR SOURCE FILE [IbatisBatchItemWriter.java]

nameclass, %method, %block, %line, %
IbatisBatchItemWriter.java100% (2/2)82%  (9/11)82%  (145/176)77%  (27/35)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class IbatisBatchItemWriter100% (1/1)78%  (7/9)81%  (113/140)79%  (22/28)
setAssertUpdates (boolean): void 0%   (0/1)0%   (0/4)0%   (0/2)
setSqlMapClient (SqlMapClient): void 0%   (0/1)0%   (0/10)0%   (0/3)
write (List): void 100% (1/1)86%  (83/96)92%  (12/13)
<static initializer> 100% (1/1)100% (4/4)100% (1/1)
IbatisBatchItemWriter (): void 100% (1/1)100% (6/6)100% (2/2)
access$000 (IbatisBatchItemWriter): String 100% (1/1)100% (3/3)100% (1/1)
afterPropertiesSet (): void 100% (1/1)100% (9/9)100% (3/3)
setSqlMapClientTemplate (SqlMapClientTemplate): void 100% (1/1)100% (4/4)100% (2/2)
setStatementId (String): void 100% (1/1)100% (4/4)100% (2/2)
     
class IbatisBatchItemWriter$1100% (1/1)100% (2/2)89%  (32/36)71%  (5/7)
doInSqlMapClient (SqlMapExecutor): Object 100% (1/1)85%  (23/27)67%  (4/6)
IbatisBatchItemWriter$1 (IbatisBatchItemWriter, List): void 100% (1/1)100% (9/9)100% (1/1)

1/*
2 * Copyright 2006-2008 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.SQLException;
19import java.util.List;
20 
21import org.apache.commons.logging.Log;
22import org.apache.commons.logging.LogFactory;
23import org.springframework.batch.item.ItemWriter;
24import org.springframework.beans.factory.InitializingBean;
25import org.springframework.dao.EmptyResultDataAccessException;
26import org.springframework.dao.InvalidDataAccessResourceUsageException;
27import org.springframework.orm.ibatis.SqlMapClientCallback;
28import org.springframework.orm.ibatis.SqlMapClientTemplate;
29import org.springframework.util.Assert;
30 
31import com.ibatis.sqlmap.client.SqlMapClient;
32import com.ibatis.sqlmap.client.SqlMapExecutor;
33import com.ibatis.sqlmap.engine.execution.BatchException;
34import com.ibatis.sqlmap.engine.execution.BatchResult;
35 
36/**
37 * {@link ItemWriter} that uses the batching features from 
38 * {@link SqlMapClientTemplate} to execute a batch of statements for all items 
39 * provided.<br/>
40 * 
41 * The user must provide an iBATIS statement id that points to the SQL statement defined
42 * in the iBATIS SqlMap configuration.<br/>
43 * 
44 * It is expected that {@link #write(List)} is called inside a transaction.<br/>
45 * 
46 * The writer is thread safe after its properties are set (normal singleton
47 * behavior), so it can be used to write in multiple concurrent transactions.
48 * 
49 * @author Thomas Risberg
50 * @since 2.0
51 */
52public class IbatisBatchItemWriter<T> implements ItemWriter<T>, InitializingBean {
53 
54        protected static final Log logger = LogFactory.getLog(IbatisBatchItemWriter.class);
55 
56        private SqlMapClientTemplate sqlMapClientTemplate;
57 
58        private String statementId;
59 
60        private boolean assertUpdates = true;
61 
62        /**
63         * Public setter for the flag that determines whether an assertion is made
64         * that all items cause at least one row to be updated.
65         * 
66         * @param assertUpdates the flag to set. Defaults to true;
67         */
68        public void setAssertUpdates(boolean assertUpdates) {
69                this.assertUpdates = assertUpdates;
70        }
71 
72        /**
73         * Public setter for {@link SqlMapClient} for injection purposes.
74         * 
75         * @param sqlMapClient the SqlMapClient
76         */
77        public void setSqlMapClient(SqlMapClient sqlMapClient) {
78                if (sqlMapClientTemplate == null) {
79                        this.sqlMapClientTemplate = new SqlMapClientTemplate(sqlMapClient);
80                }
81        }
82 
83        /**
84         * Public setter for the {@link SqlMapClientTemplate}.
85         * 
86         * @param sqlMapClientTemplate the SqlMapClientTemplate
87         */
88        public void setSqlMapClientTemplate(SqlMapClientTemplate sqlMapClientTemplate) {
89                this.sqlMapClientTemplate = sqlMapClientTemplate;
90        }
91 
92        /**
93         * Public setter for the statement id identifying the statement in the SqlMap 
94         * configuration file.
95         * 
96         * @param statementId the id for the statement
97         */
98        public void setStatementId(String statementId) {
99                this.statementId = statementId;
100        }
101 
102        /**
103         * Check mandatory properties - there must be an SqlMapClient and a statementId.
104         */
105        public void afterPropertiesSet() {
106                Assert.notNull(sqlMapClientTemplate, "A SqlMapClient or a SqlMapClientTemplate is required.");
107                Assert.notNull(statementId, "A statementId is required.");
108        }
109        
110        /* (non-Javadoc)
111         * @see org.springframework.batch.item.ItemWriter#write(java.util.List)
112         */
113        public void write(final List<? extends T> items) {
114 
115                if (!items.isEmpty()) {
116 
117                        if (logger.isDebugEnabled()) {
118                                logger.debug("Executing batch with " + items.size() + " items.");
119                        }
120                        
121                        @SuppressWarnings("unchecked")
122                        List<BatchResult> results = (List<BatchResult>) sqlMapClientTemplate.execute(
123                                        new SqlMapClientCallback() {
124                                                public Object doInSqlMapClient(SqlMapExecutor executor)
125                                                                throws SQLException {
126                                                        executor.startBatch();
127                                                        for (T item : items) {
128                                                                executor.update(statementId, item);
129                                                        }
130                                                        try {
131                                                                return executor.executeBatchDetailed();
132                                                        } catch (BatchException e) {
133                                                                throw e.getBatchUpdateException();
134                                                        }
135                                                }
136                                        });
137                        
138                        if (assertUpdates) {
139                                if (results.size() != 1) {
140                                        throw new InvalidDataAccessResourceUsageException("Batch execution returned invalid results. " +
141                                                        "Expected 1 but number of BatchResult objects returned was " + results.size());
142                                }
143                                
144                                int[] updateCounts = results.get(0).getUpdateCounts();  
145 
146                                for (int i = 0; i < updateCounts.length; i++) {
147                                        int value = updateCounts[i];
148                                        if (value == 0) {
149                                                throw new EmptyResultDataAccessException("Item " + i + " of " + updateCounts.length
150                                                                + " did not update any rows: [" + items.get(i) + "]", 1);
151                                        }
152                                }
153                        }
154 
155                }
156 
157        }
158 
159}

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