Finally: tracked build failure to odd number of items in customer table (after skip sample)
This commit is contained in:
@@ -19,6 +19,7 @@ package org.springframework.batch.item.database;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@@ -32,7 +33,6 @@ import org.springframework.batch.item.ExecutionContext;
|
||||
import org.springframework.batch.item.ItemStreamException;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.jdbc.core.RowCallbackHandler;
|
||||
import org.springframework.jdbc.core.RowMapper;
|
||||
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -179,23 +179,34 @@ public class JdbcPagingItemReader<T> extends AbstractPagingItemReader<T> impleme
|
||||
@Override
|
||||
protected void doReadPage() {
|
||||
|
||||
PagingRowCallbackHandler rowCallback = new PagingRowCallbackHandler();
|
||||
if (results == null) {
|
||||
results = new CopyOnWriteArrayList<T>();
|
||||
}
|
||||
else {
|
||||
results.clear();
|
||||
}
|
||||
|
||||
PagingRowMapper rowCallback = new PagingRowMapper();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
List query;
|
||||
|
||||
if (getPage() == 0) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("SQL used for reading first page: [" + firstPageSql + "]");
|
||||
}
|
||||
if (parameterValues != null && parameterValues.size() > 0) {
|
||||
if (this.queryProvider.isUsingNamedParameters()) {
|
||||
simpleJdbcTemplate.getNamedParameterJdbcOperations().query(firstPageSql,
|
||||
query = simpleJdbcTemplate.getNamedParameterJdbcOperations().query(firstPageSql,
|
||||
getParameterMap(parameterValues, null), rowCallback);
|
||||
}
|
||||
else {
|
||||
simpleJdbcTemplate.getJdbcOperations().query(firstPageSql,
|
||||
query = simpleJdbcTemplate.getJdbcOperations().query(firstPageSql,
|
||||
getParameterList(parameterValues, null).toArray(), rowCallback);
|
||||
}
|
||||
}
|
||||
else {
|
||||
simpleJdbcTemplate.getJdbcOperations().query(firstPageSql, rowCallback);
|
||||
query = simpleJdbcTemplate.getJdbcOperations().query(firstPageSql, rowCallback);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -204,22 +215,18 @@ public class JdbcPagingItemReader<T> extends AbstractPagingItemReader<T> impleme
|
||||
logger.debug("SQL used for reading remaining pages: [" + remainingPagesSql + "]");
|
||||
}
|
||||
if (this.queryProvider.isUsingNamedParameters()) {
|
||||
simpleJdbcTemplate.getNamedParameterJdbcOperations().query(remainingPagesSql,
|
||||
query = simpleJdbcTemplate.getNamedParameterJdbcOperations().query(remainingPagesSql,
|
||||
getParameterMap(parameterValues, startAfterValue), rowCallback);
|
||||
}
|
||||
else {
|
||||
simpleJdbcTemplate.getJdbcOperations().query(remainingPagesSql,
|
||||
query = simpleJdbcTemplate.getJdbcOperations().query(remainingPagesSql,
|
||||
getParameterList(parameterValues, startAfterValue).toArray(), rowCallback);
|
||||
}
|
||||
}
|
||||
|
||||
if (results == null) {
|
||||
results = new CopyOnWriteArrayList<T>();
|
||||
}
|
||||
else {
|
||||
results.clear();
|
||||
}
|
||||
results.addAll(rowCallback.getResults());
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Collection<T> result = query;
|
||||
results.addAll(result);
|
||||
|
||||
}
|
||||
|
||||
@@ -301,17 +308,10 @@ public class JdbcPagingItemReader<T> extends AbstractPagingItemReader<T> impleme
|
||||
return parameterList;
|
||||
}
|
||||
|
||||
private class PagingRowCallbackHandler implements RowCallbackHandler {
|
||||
private final List<T> results = new ArrayList<T>();
|
||||
|
||||
public List<T> getResults() {
|
||||
return results;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void processRow(ResultSet rs) throws SQLException {
|
||||
private class PagingRowMapper implements RowMapper {
|
||||
public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
|
||||
startAfterValue = rs.getObject(queryProvider.getSortKey());
|
||||
results.add((T) rowMapper.mapRow(rs, results.size()));
|
||||
return rowMapper.mapRow(rs, rowNum);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ DROP TABLE ERROR_LOG IF EXISTS;
|
||||
CREATE TABLE CUSTOMER_SEQ (
|
||||
ID BIGINT IDENTITY
|
||||
);
|
||||
INSERT INTO CUSTOMER_SEQ (ID) values (5);
|
||||
INSERT INTO CUSTOMER_SEQ (ID) values (4);
|
||||
CREATE TABLE BATCH_STAGING_SEQ (
|
||||
ID BIGINT IDENTITY
|
||||
);
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
</bean>
|
||||
|
||||
<bean id="incrementerParent" parent="${batch.database.incrementer.parent}">
|
||||
<property name="incrementerName" value="DUMMY" />
|
||||
<property name="incrementerName" value="DUMMY"/>
|
||||
</bean>
|
||||
|
||||
<!--import resource="alt-data-source-context.xml" /-->
|
||||
|
||||
@@ -24,7 +24,7 @@ log4j.appender.chainsaw.layout=org.apache.log4j.xml.XMLLayout
|
||||
### enable spring
|
||||
#log4j.logger.org.springframework=info
|
||||
#log4j.logger.org.springframework.transaction=debug
|
||||
log4j.logger.org.springframework.jdbc.core=debug
|
||||
#log4j.logger.org.springframework.jdbc.core=debug
|
||||
#log4j.logger.org.springframework.orm=debug
|
||||
|
||||
### debug your specific package or classes with the following example
|
||||
|
||||
@@ -15,9 +15,6 @@
|
||||
<bean id="jobRepository" class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean"
|
||||
p:dataSource-ref="dataSource" p:transactionManager-ref="transactionManager" />
|
||||
|
||||
<bean id="mapJobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean"
|
||||
lazy-init="true" autowire-candidate="false" />
|
||||
|
||||
<bean id="jobOperator" class="org.springframework.batch.core.launch.support.SimpleJobOperator" p:jobLauncher-ref="jobLauncher"
|
||||
p:jobExplorer-ref="jobExplorer" p:jobRepository-ref="jobRepository" p:jobRegistry-ref="jobRegistry" />
|
||||
|
||||
@@ -44,5 +41,10 @@
|
||||
</bean>
|
||||
|
||||
<bean id="logAdvice" class="org.springframework.batch.sample.common.LogAdvice" />
|
||||
|
||||
<bean id="customerIncrementer" parent="incrementerParent">
|
||||
<property name="incrementerName" value="CUSTOMER_SEQ" />
|
||||
</bean>
|
||||
|
||||
|
||||
</beans>
|
||||
|
||||
@@ -25,7 +25,9 @@ import org.springframework.batch.core.repository.JobRestartException;
|
||||
import org.springframework.batch.sample.common.SkipCheckingListener;
|
||||
import org.springframework.batch.sample.domain.trade.internal.TradeWriter;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
|
||||
import org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.jdbc.SimpleJdbcTestUtils;
|
||||
@@ -49,6 +51,10 @@ public class SkipSampleFunctionalTests {
|
||||
@Autowired
|
||||
private JobOperator jobOperator;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("customerIncrementer")
|
||||
private DataFieldMaxValueIncrementer incrementer;
|
||||
|
||||
@Autowired
|
||||
public void setDataSource(DataSource dataSource) {
|
||||
this.simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);
|
||||
@@ -59,7 +65,7 @@ public class SkipSampleFunctionalTests {
|
||||
simpleJdbcTemplate.update("DELETE from TRADE");
|
||||
simpleJdbcTemplate.update("DELETE from CUSTOMER");
|
||||
for (int i = 1; i < 10; i++) {
|
||||
simpleJdbcTemplate.update("INSERT INTO CUSTOMER VALUES (" + i + ", 0, 'customer" + i + "', 100000)");
|
||||
simpleJdbcTemplate.update("INSERT INTO CUSTOMER (ID, VERSION, NAME, CREDIT) VALUES (" + incrementer.nextIntValue() + ", 0, 'customer" + i + "', 100000)");
|
||||
}
|
||||
simpleJdbcTemplate.update("DELETE from ERROR_LOG");
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.batch.sample.domain.trade.Trade;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.jdbc.core.RowCallbackHandler;
|
||||
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
|
||||
import org.springframework.jdbc.support.incrementer.AbstractDataFieldMaxValueIncrementer;
|
||||
@@ -51,7 +52,7 @@ public class JdbcTradeWriterTests {
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setIncrementer(AbstractDataFieldMaxValueIncrementer incrementer) {
|
||||
public void setIncrementer(@Qualifier("incrementerParent") AbstractDataFieldMaxValueIncrementer incrementer) {
|
||||
incrementer.setIncrementerName("TRADE_SEQ");
|
||||
this.writer.setIncrementer(incrementer);
|
||||
}
|
||||
|
||||
@@ -19,6 +19,9 @@ package org.springframework.batch.sample.iosample;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.junit.Test;
|
||||
@@ -51,8 +54,9 @@ public class JdbcPagingRestartIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
private ItemReader<CustomerCredit> reader;
|
||||
|
||||
private SimpleJdbcTemplate jdbcTemplate;
|
||||
|
||||
|
||||
@Autowired
|
||||
public void setDataSource(DataSource dataSource) {
|
||||
jdbcTemplate = new SimpleJdbcTemplate(dataSource);
|
||||
@@ -65,21 +69,36 @@ public class JdbcPagingRestartIntegrationTests {
|
||||
|
||||
@Test
|
||||
public void testReader() throws Exception {
|
||||
|
||||
int total = SimpleJdbcTestUtils.countRowsInTable(jdbcTemplate, "CUSTOMER");
|
||||
int pageSize = 2; // same as configured in reader
|
||||
int count = (total / pageSize) * pageSize;
|
||||
if (count >= pageSize) {
|
||||
count -= pageSize;
|
||||
}
|
||||
|
||||
ExecutionContext executionContext = new ExecutionContext();
|
||||
int count = SimpleJdbcTestUtils.countRowsInTable(jdbcTemplate, "CUSTOMER")-2;
|
||||
executionContext.putInt("JdbcPagingItemReader.read.count", count);
|
||||
// Assume the primary keys are in order
|
||||
executionContext.putInt("JdbcPagingItemReader.start.after", count);
|
||||
((ItemStream)reader).open(executionContext);
|
||||
|
||||
List<Map<String, Object>> ids = jdbcTemplate
|
||||
.queryForList("SELECT ID, CREDIT FROM CUSTOMER WHERE CREDIT > 10000 ORDER BY ID ASC");
|
||||
// System.err.println(ids);
|
||||
int startAfterValue = ((Long) ids.get(count - 1).get("ID")).intValue();
|
||||
// System.err.println("Start after: " + startAfterValue);
|
||||
executionContext.putInt("JdbcPagingItemReader.start.after", startAfterValue);
|
||||
((ItemStream) reader).open(executionContext);
|
||||
|
||||
for (int i = count; i < total; i++) {
|
||||
CustomerCredit item = reader.read();
|
||||
// System.err.println("Item: " + item);
|
||||
assertNotNull(item);
|
||||
}
|
||||
|
||||
CustomerCredit item = reader.read();
|
||||
// System.err.println(item);
|
||||
assertNotNull(item);
|
||||
item = reader.read();
|
||||
// System.err.println(item);
|
||||
assertNotNull(item);
|
||||
item = reader.read();
|
||||
// System.err.println(item);
|
||||
// System.err.println("Item: " + item);
|
||||
assertNull(item);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user