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:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
|
||||
Reference in New Issue
Block a user