Introduce KeyedItemReader to push the getKey() method into a separate place.

This commit is contained in:
dsyer
2008-01-30 08:55:53 +00:00
parent 152829ba5f
commit 6ffefbc184
31 changed files with 139 additions and 115 deletions

View File

@@ -18,7 +18,6 @@ package org.springframework.batch.core.domain;
import java.util.List;
import org.springframework.batch.io.exception.BatchCriticalException;
import org.springframework.batch.repeat.ExitStatus;
/**
* Batch domain object representing a job. Job is an explicit abstraction
@@ -39,6 +38,6 @@ public interface Job {
boolean isRestartable();
ExitStatus run(JobExecution execution) throws BatchCriticalException;
void run(JobExecution execution) throws BatchCriticalException;
}

View File

@@ -20,7 +20,6 @@ import java.util.ArrayList;
import java.util.List;
import org.springframework.batch.io.exception.BatchCriticalException;
import org.springframework.batch.repeat.ExitStatus;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.util.ClassUtils;
@@ -134,7 +133,7 @@ public class JobSupport implements BeanNameAware, Job {
/* (non-Javadoc)
* @see org.springframework.batch.core.domain.Job#run(org.springframework.batch.core.domain.JobExecution)
*/
public ExitStatus run(JobExecution execution) throws BatchCriticalException {
public void run(JobExecution execution) throws BatchCriticalException {
throw new UnsupportedOperationException("JobSupport does not provide an implementation of run(). Use a smarter subclass.");
}

View File

@@ -16,14 +16,12 @@
package org.springframework.batch.core.domain;
import org.springframework.batch.io.exception.BatchCriticalException;
import org.springframework.batch.repeat.ExitStatus;
/**
* Batch domain interface representing the configuration of a step. As with the
* (@link Job), step configuration is meant to explicitly represent
* a the configuration of a step by a developer. This allows for the separation
* of what a developer configures from the myriad of concerns required for
* (@link Job), step configuration is meant to explicitly represent a the
* configuration of a step by a developer. This allows for the separation of
* what a developer configures from the myriad of concerns required for
* executing a job.
*
* @author Dave Syer
@@ -41,7 +39,7 @@ public interface Step {
* again.
*/
boolean isAllowStartIfComplete();
/**
* Flag to indicate if restart data needs to be saved for this step.
* @return true if restart data should be saved
@@ -53,11 +51,15 @@ public interface Step {
* identifier.
*/
int getStartLimit();
/**
* It is not safe to re-use an instance of {@link StepExecutor} to process
* multiple concurrent executions. Use the factory method in {@link Step} to
* create a new instance and execute that.
* Process the step and assign progress and status meta information to the
* {@link StepExecution} provided. The {@link Step} is responsible for
* setting the meta information and also saving it if required by the
* implementation.<br/>
*
* It is not safe to re-use an instance of {@link Step} to process multiple
* concurrent executions.
*
* @param stepExecution an entity representing the step to be executed
*
@@ -65,6 +67,6 @@ public interface Step {
* @throws BatchCriticalException if there is a problem that needs to be
* signalled to the caller
*/
ExitStatus process(StepExecution stepExecution) throws StepInterruptedException, BatchCriticalException;
void process(StepExecution stepExecution) throws StepInterruptedException, BatchCriticalException;
}

View File

@@ -136,7 +136,7 @@ public class StepSupport implements Step, BeanNameAware {
*
* @see org.springframework.batch.core.domain.Step#process(org.springframework.batch.core.domain.StepExecution)
*/
public org.springframework.batch.repeat.ExitStatus process(StepExecution stepExecution)
public void process(StepExecution stepExecution)
throws StepInterruptedException, BatchCriticalException {
throw new UnsupportedOperationException(
"Cannot process a StepExecution. Use a smarter subclass of StepSupport.");

View File

@@ -55,7 +55,7 @@ public class SimpleJob extends JobSupport {
*
* @see org.springframework.batch.core.domain.Job#run(org.springframework.batch.core.domain.JobExecution)
*/
public ExitStatus run(JobExecution execution) throws BatchCriticalException {
public void run(JobExecution execution) throws BatchCriticalException {
JobInstance jobInstance = execution.getJobInstance();
updateStatus(execution, BatchStatus.STARTING);
@@ -78,7 +78,8 @@ public class SimpleJob extends JobSupport {
startedCount++;
updateStatus(execution, BatchStatus.STARTED);
StepExecution stepExecution = execution.createStepExecution(stepInstance);
status = step.process(stepExecution);
step.process(stepExecution);
status = stepExecution.getExitStatus();
}
}
@@ -111,7 +112,6 @@ public class SimpleJob extends JobSupport {
jobRepository.saveOrUpdate(execution);
}
return status;
}
private void updateStatus(JobExecution jobExecution, BatchStatus status) {

View File

@@ -24,7 +24,6 @@ import org.springframework.batch.core.domain.JobParameters;
import org.springframework.batch.core.domain.JobSupport;
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.repeat.ExitStatus;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.task.SyncTaskExecutor;
import org.springframework.core.task.TaskExecutor;
@@ -83,10 +82,7 @@ public class SimpleJobLauncher implements JobLauncher, InitializingBean {
public void run() {
try {
logger.info("Job: [" + job + "] launched with the following parameters: [" + jobParameters + "]");
ExitStatus exitStatus = job.run(jobExecution);
// The exit status should be set by the Job. TODO: remove
// this line...
jobExecution.setExitStatus(exitStatus);
job.run(jobExecution);
logger.info("Job: [" + job + "] completed successfully with the following parameters: ["
+ jobParameters + "]");
}

View File

@@ -22,7 +22,6 @@ import org.springframework.batch.core.domain.StepSupport;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.tasklet.Tasklet;
import org.springframework.batch.io.exception.BatchCriticalException;
import org.springframework.batch.repeat.ExitStatus;
import org.springframework.batch.repeat.exception.handler.ExceptionHandler;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.util.Assert;
@@ -112,9 +111,9 @@ public abstract class AbstractStep extends StepSupport {
/* (non-Javadoc)
* @see org.springframework.batch.core.domain.StepSupport#process(org.springframework.batch.core.domain.StepExecution)
*/
public ExitStatus process(StepExecution stepExecution) throws StepInterruptedException, BatchCriticalException {
public void process(StepExecution stepExecution) throws StepInterruptedException, BatchCriticalException {
SimpleStepExecutor executor = createStepExecutor();
return executor.process(stepExecution);
executor.process(stepExecution);
}
/**

View File

@@ -20,7 +20,6 @@ import org.springframework.batch.core.domain.Step;
import org.springframework.batch.core.domain.StepExecution;
import org.springframework.batch.core.domain.StepInterruptedException;
import org.springframework.batch.io.exception.BatchCriticalException;
import org.springframework.batch.repeat.ExitStatus;
import org.springframework.batch.repeat.RepeatOperations;
/**
@@ -78,7 +77,7 @@ public class RepeatOperationsStep extends AbstractStep implements RepeatOperatio
/* (non-Javadoc)
* @see org.springframework.batch.execution.step.simple.AbstractStep#process(org.springframework.batch.core.domain.StepExecution)
*/
public ExitStatus process(StepExecution stepExecution) throws StepInterruptedException, BatchCriticalException {
public void process(StepExecution stepExecution) throws StepInterruptedException, BatchCriticalException {
assertMandatoryProperties();
SimpleStepExecutor executor = (SimpleStepExecutor) super.createStepExecutor();
if (stepOperations != null) {
@@ -87,6 +86,6 @@ public class RepeatOperationsStep extends AbstractStep implements RepeatOperatio
if (chunkOperations != null) {
executor.setChunkOperations(chunkOperations);
}
return executor.process(stepExecution);
executor.process(stepExecution);
}
}

View File

@@ -173,7 +173,7 @@ public class SimpleStepExecutor {
* execution
* @see StepExecutor#process(StepExecution)
*/
public ExitStatus process(final StepExecution stepExecution) throws BatchCriticalException,
public void process(final StepExecution stepExecution) throws BatchCriticalException,
StepInterruptedException {
final StepInstance stepInstance = stepExecution.getStep();
@@ -276,7 +276,6 @@ public class SimpleStepExecutor {
});
updateStatus(stepExecution, BatchStatus.COMPLETED);
return status;
}
catch (RuntimeException e) {

View File

@@ -21,6 +21,7 @@ import org.springframework.batch.io.Skippable;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemRecoverer;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.KeyedItemReader;
import org.springframework.batch.repeat.ExitStatus;
import org.springframework.batch.retry.RetryPolicy;
import org.springframework.batch.retry.callback.ItemReaderRetryCallback;
@@ -111,7 +112,8 @@ public class ItemOrientedTasklet implements Tasklet, Skippable, InitializingBean
template.setRetryPolicy(itemProviderRetryPolicy);
if (retryPolicy != null) {
retryCallback = new ItemReaderRetryCallback(itemProvider, itemWriter);
Assert.state(itemProvider instanceof KeyedItemReader, "ItemReader must be instance of KeyedItemReader to use the retry policy");
retryCallback = new ItemReaderRetryCallback((KeyedItemReader) itemProvider, itemWriter);
retryCallback.setRecoverer(itemRecoverer);
}

View File

@@ -272,7 +272,7 @@ public class SimpleJobTests extends TestCase {
this.runnable = runnable;
}
public ExitStatus process(StepExecution stepExecution) throws StepInterruptedException, BatchCriticalException {
public void process(StepExecution stepExecution) throws StepInterruptedException, BatchCriticalException {
if (exception instanceof RuntimeException) {
throw (RuntimeException)exception;
}
@@ -282,7 +282,7 @@ public class SimpleJobTests extends TestCase {
if (runnable!=null) {
runnable.run();
}
return ExitStatus.FINISHED;
stepExecution.setExitStatus(ExitStatus.FINISHED);
}
}

View File

@@ -41,8 +41,9 @@ public class SimpleJobLauncherTests extends TestCase {
private MockControl repositoryControl = MockControl.createControl(JobRepository.class);
private Job job = new JobSupport("foo") {
public ExitStatus run(JobExecution execution) {
return ExitStatus.FINISHED;
public void run(JobExecution execution) {
execution.setExitStatus(ExitStatus.FINISHED);
return;
}
};
@@ -88,7 +89,7 @@ public class SimpleJobLauncherTests extends TestCase {
public void testRunWithException() throws Exception {
job = new JobSupport() {
public ExitStatus run(JobExecution execution) {
public void run(JobExecution execution) {
execution.setExitStatus(ExitStatus.FAILED);
throw new RuntimeException("foo");
}
@@ -104,7 +105,7 @@ public class SimpleJobLauncherTests extends TestCase {
public void testRunWithError() throws Exception {
job = new JobSupport() {
public ExitStatus run(JobExecution execution) {
public void run(JobExecution execution) {
execution.setExitStatus(ExitStatus.FAILED);
throw new Error("foo");
}

View File

@@ -27,6 +27,7 @@ import org.springframework.batch.io.Skippable;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemRecoverer;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.KeyedItemReader;
import org.springframework.batch.item.reader.AbstractItemReader;
import org.springframework.batch.item.writer.AbstractItemWriter;
import org.springframework.batch.repeat.context.RepeatContextSupport;
@@ -217,11 +218,7 @@ public class ItemOrientedTaskletTests extends TestCase {
return true;
}
});
module.setItemReader(new AbstractItemReader() {
public Object read() throws Exception {
return "foo";
}
});
module.setItemReader(new MockItemReader());
module.setItemWriter(new AbstractItemWriter() {
public void write(Object data) throws Exception {
throw new RuntimeException("FOO");
@@ -267,7 +264,16 @@ public class ItemOrientedTaskletTests extends TestCase {
}
}
private class SkippableItemReader implements ItemReader,
private class MockItemReader extends AbstractItemReader implements KeyedItemReader {
public Object read() throws Exception {
return "foo";
}
public Object getKey(Object item) {
return item;
}
}
private class SkippableItemReader implements KeyedItemReader,
Skippable, StatisticsProvider {
public Object read() throws Exception {
return itemProvider.read();

View File

@@ -55,10 +55,6 @@ public class RestartableItemOrientedTaskletTests extends TestCase {
assertEquals(this.data.getProperties(), data.getProperties());
}
public Object getKey(Object item) {
return null;
}
public boolean recover(Object data, Throwable cause) {
return false;
}

View File

@@ -31,7 +31,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.batch.io.Skippable;
import org.springframework.batch.io.support.AbstractTransactionalIoSource;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.KeyedItemReader;
import org.springframework.batch.item.ResourceLifecycle;
import org.springframework.batch.restart.GenericRestartData;
import org.springframework.batch.restart.RestartData;
@@ -117,7 +117,7 @@ import org.springframework.util.StringUtils;
* @author Peter Zozom
*/
public class JdbcCursorItemReader extends AbstractTransactionalIoSource
implements ItemReader, ResourceLifecycle, DisposableBean,
implements KeyedItemReader, ResourceLifecycle, DisposableBean,
InitializingBean, Restartable, StatisticsProvider, Skippable {
private static Log log = LogFactory.getLog(JdbcCursorItemReader.class);

View File

@@ -19,7 +19,7 @@ import java.util.Iterator;
import java.util.List;
import org.springframework.batch.io.support.AbstractTransactionalIoSource;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.KeyedItemReader;
import org.springframework.batch.item.ResourceLifecycle;
import org.springframework.batch.repeat.synch.BatchTransactionSynchronizationManager;
import org.springframework.batch.restart.RestartData;
@@ -51,7 +51,7 @@ import org.springframework.util.Assert;
* @since 1.0
*/
public class DrivingQueryItemReader extends AbstractTransactionalIoSource
implements ItemReader, ResourceLifecycle, InitializingBean,
implements KeyedItemReader, ResourceLifecycle, InitializingBean,
DisposableBean, Restartable {
private boolean initialized = false;

View File

@@ -16,9 +16,10 @@
package org.springframework.batch.item;
import org.springframework.batch.item.reader.AbstractItemReader;
/**
* Strategy interface for providing the data for a given batch stage execution.
* <br/>
* Strategy interface for providing the data. <br/>
*
* Implementations are expected to be stateful and will be called multiple times
* for each batch, with each call to {@link #next} returning a different value
@@ -26,8 +27,8 @@ package org.springframework.batch.item;
*
* Implementations need to be thread safe and clients of a {@link ItemReader}
* need to be aware that this is the case. Clients can code to this interface
* without worrying about thread safety by using the AbstractItemProvider base
* class.<br/>
* without worrying about thread safety by using the {@link AbstractItemReader}
* base class.<br/>
*
* A richer interface (e.g. with a look ahead or peek) is not feasible because
* we need to support transactions in an asynchronous batch.
@@ -50,15 +51,6 @@ public interface ItemReader {
*/
Object read() throws Exception;
/**
* Get a unique identifier for the item that can be used to cache it between
* calls if necessary, and then identify it later.
*
* @param item the current item.
* @return a unique identifier.
*/
Object getKey(Object item);
/**
* Close the reader, freeing any resources that may have been allocated
* since the first call to read().

View File

@@ -0,0 +1,36 @@
/*
* Copyright 2006-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.item;
/**
* Extension of the {@link ItemReader} interface that allows items to be
* identified and tagged by a unique key.
*
* @author Dave Syer
*
*/
public interface KeyedItemReader extends ItemReader {
/**
* Get a unique identifier for the item that can be used to cache it between
* calls if necessary, and then identify it later.
*
* @param item the current item.
* @return a unique identifier.
*/
Object getKey(Object item);
}

View File

@@ -24,18 +24,11 @@ import org.springframework.batch.item.ItemReader;
*
*/
public abstract class AbstractItemReader implements ItemReader {
/**
* Simply returns the item itself. Will be adequate for many purposes, but
* not (for example) if the item is a message - in which case the identifier
* should be used.
*
* @see org.springframework.batch.item.ItemReader#getKey(java.lang.Object)
*/
public Object getKey(Object item) {
return item;
}
/**
* Do nothing.
* @see org.springframework.batch.item.ItemReader#close()
*/
public void close() throws Exception {
}

View File

@@ -33,11 +33,11 @@ public class ItemReaderAdapter extends AbstractMethodInvokingDelegator implement
return invokeDelegateMethod();
}
//harmless implementation of method required by ItemReader interface
public Object getKey(Object item) {
return item;
}
/**
* Do nothing.
*
* @see org.springframework.batch.item.ItemReader#close()
*/
public void close() throws Exception {
}

View File

@@ -24,6 +24,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.batch.item.FailedItemIdentifier;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.KeyedItemReader;
import org.springframework.batch.item.exception.UnexpectedInputException;
import org.springframework.jms.JmsException;
import org.springframework.jms.core.JmsOperations;
@@ -39,7 +40,7 @@ import org.springframework.util.Assert;
* @author Dave Syer
*
*/
public class JmsItemReader extends AbstractItemReader implements FailedItemIdentifier {
public class JmsItemReader extends AbstractItemReader implements KeyedItemReader, FailedItemIdentifier {
protected Log logger = LogFactory.getLog(getClass());
@@ -151,7 +152,7 @@ public class JmsItemReader extends AbstractItemReader implements FailedItemIdent
throw new UnexpectedInputException("Could not extract message ID", e);
}
}
return super.getKey(item);
return item;
}
/**

View File

@@ -21,6 +21,7 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemRecoverer;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.KeyedItemReader;
import org.springframework.batch.retry.RetryCallback;
import org.springframework.batch.retry.RetryContext;
import org.springframework.batch.retry.RetryPolicy;
@@ -47,13 +48,13 @@ public class ItemReaderRetryCallback implements RetryCallback {
public static final String ITEM = ItemReaderRetryCallback.class.getName()
+ ".ITEM";
private ItemReader provider;
private KeyedItemReader provider;
private ItemWriter writer;
private ItemRecoverer recoverer;
public ItemReaderRetryCallback(ItemReader provider,
public ItemReaderRetryCallback(KeyedItemReader provider,
ItemWriter writer) {
super();
this.provider = provider;
@@ -127,7 +128,7 @@ public class ItemReaderRetryCallback implements RetryCallback {
*
* @return the {@link ItemReader} instance.
*/
public ItemReader getReader() {
public KeyedItemReader getReader() {
return provider;
}

View File

@@ -19,8 +19,8 @@ package org.springframework.batch.retry.policy;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.batch.item.FailedItemIdentifier;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemRecoverer;
import org.springframework.batch.item.KeyedItemReader;
import org.springframework.batch.repeat.synch.RepeatSynchronizationManager;
import org.springframework.batch.retry.RetryCallback;
import org.springframework.batch.retry.RetryContext;
@@ -109,7 +109,7 @@ public class ItemReaderRetryPolicy extends AbstractStatefulRetryPolicy {
public RetryContext open(RetryCallback callback) {
Assert.state(callback instanceof ItemReaderRetryCallback,
"Callback must be ItemProviderRetryCallback");
ItemProviderRetryContext context = new ItemProviderRetryContext(
ItemReaderRetryContext context = new ItemReaderRetryContext(
(ItemReaderRetryCallback) callback);
context.open(callback);
return context;
@@ -137,7 +137,7 @@ public class ItemReaderRetryPolicy extends AbstractStatefulRetryPolicy {
return ((RetryPolicy) context).handleRetryExhausted(context);
}
private class ItemProviderRetryContext extends RetryContextSupport
private class ItemReaderRetryContext extends RetryContextSupport
implements RetryPolicy {
private Object item;
@@ -145,11 +145,11 @@ public class ItemReaderRetryPolicy extends AbstractStatefulRetryPolicy {
// The delegate context...
private RetryContext delegateContext;
private ItemReader reader;
private KeyedItemReader reader;
private ItemRecoverer recoverer;
public ItemProviderRetryContext(ItemReaderRetryCallback callback) {
public ItemReaderRetryContext(ItemReaderRetryCallback callback) {
super(RetrySynchronizationManager.getContext());
item = callback.next(this);
this.reader = callback.getReader();
@@ -239,7 +239,7 @@ public class ItemReaderRetryPolicy extends AbstractStatefulRetryPolicy {
* @param item
* @return
*/
protected boolean hasFailed(ItemReader provider, Object item) {
protected boolean hasFailed(KeyedItemReader provider, Object item) {
if (provider instanceof FailedItemIdentifier) {
return ((FailedItemIdentifier) provider).hasFailed(item);
}

View File

@@ -41,14 +41,6 @@ public class DelegatingItemReaderIntegrationTests extends AbstractDependencyInje
}
}
/**
* getKey(..) is implemented trivially.
*/
public void testGetKey() {
Object item = new Object();
assertSame(item, provider.getKey(item));
}
public void setProvider(ItemReaderAdapter provider) {
this.provider = provider;
}

View File

@@ -18,11 +18,11 @@ package org.springframework.batch.retry;
import java.util.List;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemRecoverer;
import org.springframework.batch.item.KeyedItemReader;
import org.springframework.batch.item.reader.ListItemReader;
public class ListItemReaderRecoverer extends ListItemReader implements ItemReader, ItemRecoverer {
public class ListItemReaderRecoverer extends ListItemReader implements KeyedItemReader, ItemRecoverer {
/**
* Delegate to super class constructor.
@@ -43,5 +43,14 @@ public class ListItemReaderRecoverer extends ListItemReader implements ItemReade
public boolean recover(Object item, Throwable cause) {
return false;
}
/**
* Return the item (assume it is its own key).
*
* @see org.springframework.batch.item.KeyedItemReader#getKey(java.lang.Object)
*/
public Object getKey(Object item) {
return item;
}
}

View File

@@ -22,7 +22,6 @@ import java.util.List;
import junit.framework.TestCase;
import org.springframework.batch.item.reader.ListItemReader;
import org.springframework.batch.item.writer.AbstractItemWriter;
import org.springframework.batch.retry.ListItemReaderRecoverer;
import org.springframework.batch.retry.RetryContext;
@@ -40,7 +39,7 @@ public class ItemReaderRetryCallbackTests extends TestCase {
RetryTemplate template;
ListItemReader provider;
ListItemReaderRecoverer provider;
ItemReaderRetryCallback callback;

View File

@@ -24,7 +24,7 @@ import java.util.List;
import junit.framework.TestCase;
import org.springframework.batch.item.FailedItemIdentifier;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.KeyedItemReader;
import org.springframework.batch.item.reader.ListItemReader;
import org.springframework.batch.item.writer.AbstractItemWriter;
import org.springframework.batch.repeat.RepeatContext;
@@ -41,7 +41,7 @@ public class ItemReaderRetryPolicyTests extends TestCase {
private ItemReaderRetryPolicy policy = new ItemReaderRetryPolicy();
private ItemReader provider;
private org.springframework.batch.item.KeyedItemReader provider;
private int count = 0;
@@ -299,7 +299,7 @@ public class ItemReaderRetryPolicyTests extends TestCase {
assertTrue(policy.hasFailed(provider, "foo"));
}
private static class MockFailedItemProvider extends ListItemReader implements FailedItemIdentifier {
private static class MockFailedItemProvider extends ListItemReader implements KeyedItemReader, FailedItemIdentifier {
private int hasFailedCount = 0;

View File

@@ -21,5 +21,8 @@ import org.springframework.batch.item.reader.AbstractItemReader;
* @author Dave Syer
*
*/
public abstract class AbstractItemReaderRecoverer extends AbstractItemReader implements ItemRecoverer {
public abstract class AbstractItemReaderRecoverer extends AbstractItemReader implements KeyedItemReader, ItemRecoverer {
public Object getKey(Object item) {
return item;
}
}

View File

@@ -22,7 +22,7 @@ import java.util.List;
import javax.sql.DataSource;
import org.springframework.batch.item.AbstractItemReaderRecoverer;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.KeyedItemReader;
import org.springframework.batch.item.writer.AbstractItemWriter;
import org.springframework.batch.repeat.ExitStatus;
import org.springframework.batch.repeat.RepeatCallback;
@@ -48,7 +48,7 @@ public class ExternalRetryInBatchTests extends AbstractDependencyInjectionSpring
private RepeatTemplate repeatTemplate;
private ItemReader provider;
private KeyedItemReader provider;
private JdbcTemplate jdbcTemplate;

View File

@@ -22,7 +22,7 @@ import java.util.List;
import javax.sql.DataSource;
import org.springframework.batch.item.AbstractItemReaderRecoverer;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.KeyedItemReader;
import org.springframework.batch.item.writer.AbstractItemWriter;
import org.springframework.batch.retry.callback.ItemReaderRetryCallback;
import org.springframework.batch.retry.policy.ItemReaderRetryPolicy;
@@ -41,7 +41,7 @@ public class ExternalRetryTests extends AbstractDependencyInjectionSpringContext
private RetryTemplate retryTemplate;
private ItemReader provider;
private KeyedItemReader provider;
private JdbcTemplate jdbcTemplate;

View File

@@ -11,7 +11,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.batch.execution.scope.StepContext;
import org.springframework.batch.execution.scope.StepContextAware;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.KeyedItemReader;
import org.springframework.batch.item.ResourceLifecycle;
import org.springframework.batch.repeat.synch.BatchTransactionSynchronizationManager;
import org.springframework.batch.sample.item.writer.StagingItemWriter;
@@ -26,7 +26,7 @@ import org.springframework.transaction.support.TransactionSynchronizationAdapter
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.util.Assert;
public class StagingItemReader extends JdbcDaoSupport implements ItemReader, ResourceLifecycle, DisposableBean,
public class StagingItemReader extends JdbcDaoSupport implements KeyedItemReader, ResourceLifecycle, DisposableBean,
StepContextAware {
// Key for buffer in transaction synchronization manager