RESOLVED - BATCH-593: Calling update before read on DrivingQueryItemReader causes ArrayIndexOutOfBoundsError

fixed bug and tested the scenario for all ItemReaders
This commit is contained in:
robokaso
2008-04-21 08:05:43 +00:00
parent b0fb4167dc
commit 90df52ac55
2 changed files with 22 additions and 19 deletions

View File

@@ -28,11 +28,11 @@ import org.springframework.util.Assert;
/**
* <p>
* Convenience class for driving query input sources. Input Sources of this type
* use a 'driving query' to return back a list of keys. A key can be defined
* as anything that can uniquely identify a record so that a more detailed
* record can be retrieved for each object. This allows a much smaller footprint
* to be stored in memory for processing. The following 'Customer' example table
* will help illustrate this:
* use a 'driving query' to return back a list of keys. A key can be defined as
* anything that can uniquely identify a record so that a more detailed record
* can be retrieved for each object. This allows a much smaller footprint to be
* stored in memory for processing. The following 'Customer' example table will
* help illustrate this:
*
* <pre>
* CREATE TABLE CUSTOMER (
@@ -42,12 +42,14 @@ import org.springframework.util.Assert;
* );
* </pre>
*
* <p>A cursor based solution would simply open up a cursor over ID, NAME, and CREDIT,
* and move it from one to the next. This can cause issues on databases with
* pessimistic locking strategies. A 'driving query' approach would be to
* <p>
* A cursor based solution would simply open up a cursor over ID, NAME, and
* CREDIT, and move it from one to the next. This can cause issues on databases
* with pessimistic locking strategies. A 'driving query' approach would be to
* return only the ID of the customer, then use a separate DAO to retrieve the
* name and credit for each ID. This means that there will be a call to a
* separate DAO for each call to {@link ItemReader#read()}.</p>
* name and credit for each ID. This means that there will be a call to a
* separate DAO for each call to {@link ItemReader#read()}.
* </p>
*
* <p>
* Mutability: Because this base class cannot guarantee that the keys returned
@@ -62,8 +64,7 @@ import org.springframework.util.Assert;
*
* @author Lucas Ward
*/
public class DrivingQueryItemReader implements ItemReader, InitializingBean,
ItemStream {
public class DrivingQueryItemReader implements ItemReader, InitializingBean, ItemStream {
private boolean initialized = false;
@@ -76,7 +77,7 @@ public class DrivingQueryItemReader implements ItemReader, InitializingBean,
private int lastCommitIndex = 0;
private KeyCollector keyGenerator;
private boolean saveState = false;
public DrivingQueryItemReader() {
@@ -113,13 +114,13 @@ public class DrivingQueryItemReader implements ItemReader, InitializingBean,
/**
* Get the current key. This method will return the same object returned by
* the last read() method. If the ItemReader hasn't been initialized yet,
* then null will be returned.
* the last read() method. If no items have been read yet the ItemReader
* yet, then null will be returned.
*
* @return the current key.
*/
protected Object getCurrentKey() {
if (initialized) {
if (initialized && currentIndex > 0) {
return keys.get(currentIndex - 1);
}
@@ -152,7 +153,7 @@ public class DrivingQueryItemReader implements ItemReader, InitializingBean,
Assert.state(keys == null && !initialized, "Cannot open an already opened input source"
+ ", call close() first.");
keys = keyGenerator.retrieveKeys(executionContext);
if(keys == null || keys.size() == 0){
if (keys == null || keys.size() == 0) {
throw new NoWorkFoundException("KeyGenerator must return at least 1 key");
}
keysIterator = keys.listIterator();
@@ -160,9 +161,9 @@ public class DrivingQueryItemReader implements ItemReader, InitializingBean,
}
public void update(ExecutionContext executionContext) {
if(saveState){
if (saveState) {
Assert.notNull(executionContext, "ExecutionContext must not be null");
if(getCurrentKey() != null){
if (getCurrentKey() != null) {
keyGenerator.updateContext(getCurrentKey(), executionContext);
}
}

View File

@@ -37,6 +37,8 @@ public abstract class CommonItemStreamItemReaderTests extends CommonItemReaderTe
*/
public void testRestart() throws Exception {
testedAsStream().update(executionContext);
Foo foo1 = (Foo) tested.read();
assertEquals(1, foo1.getValue());