Fixes the RepositoryItemReader ignoring explicitly set currentItemCount
If the user explicitly sets the currentItemCount value on a RepositoryItemReader, prior to this commit, it is ignored. this commit addresses this by moving the current counter up to the correct value when that value is set. This fix addresses BATCH-2274. This commit also addresses a number of compiler warnings around javadoc.
This commit is contained in:
@@ -15,8 +15,14 @@
|
||||
*/
|
||||
package org.springframework.batch.item.data;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.batch.item.ExecutionContext;
|
||||
import org.springframework.batch.item.adapter.AbstractMethodInvokingDelegator.InvocationTargetThrowableWrapper;
|
||||
import org.springframework.batch.item.adapter.DynamicMethodInvocationException;
|
||||
@@ -31,11 +37,6 @@ import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.MethodInvoker;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* A {@link org.springframework.batch.item.ItemReader} that reads records utilizing
|
||||
@@ -173,8 +174,8 @@ public class RepositoryItemReader<T> extends AbstractItemCountingItemStreamItemR
|
||||
@Override
|
||||
protected void jumpToItem(int itemLastIndex) throws Exception {
|
||||
synchronized (lock) {
|
||||
page = itemLastIndex / pageSize;
|
||||
current = itemLastIndex % pageSize;
|
||||
page = (itemLastIndex - 1) / pageSize;
|
||||
current = (itemLastIndex - 1) % pageSize;
|
||||
|
||||
results = doPageRead();
|
||||
page++;
|
||||
|
||||
@@ -153,7 +153,7 @@ implements InitializingBean {
|
||||
/**
|
||||
* Public setter for the data source for injection purposes.
|
||||
*
|
||||
* @param dataSource
|
||||
* @param dataSource {@link javax.sql.DataSource} to be used
|
||||
*/
|
||||
public void setDataSource(DataSource dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
@@ -172,7 +172,10 @@ implements InitializingBean {
|
||||
* Prepare the given JDBC Statement (or PreparedStatement or
|
||||
* CallableStatement), applying statement settings such as fetch size, max
|
||||
* rows, and query timeout. @param stmt the JDBC Statement to prepare
|
||||
* @throws SQLException
|
||||
*
|
||||
* @param stmt {@link java.sql.PreparedStatement} to be configured
|
||||
*
|
||||
* @throws SQLException if interactions with provided stmt fail
|
||||
*
|
||||
* @see #setFetchSize
|
||||
* @see #setMaxRows
|
||||
@@ -192,10 +195,10 @@ implements InitializingBean {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the exception translator for this instance.
|
||||
*
|
||||
* Creates a default SQLErrorCodeSQLExceptionTranslator for the specified
|
||||
* DataSource if none is set.
|
||||
*
|
||||
* @return the exception translator for this instance.
|
||||
*/
|
||||
protected SQLExceptionTranslator getExceptionTranslator() {
|
||||
synchronized(this) {
|
||||
@@ -216,7 +219,7 @@ implements InitializingBean {
|
||||
* warnings (at debug level).
|
||||
*
|
||||
* @param statement the current statement to obtain the warnings from, if there are any.
|
||||
* @throws SQLException
|
||||
* @throws SQLException if interaction with provided statement fails.
|
||||
*
|
||||
* @see org.springframework.jdbc.SQLWarningException
|
||||
*/
|
||||
@@ -461,7 +464,7 @@ implements InitializingBean {
|
||||
* @param rs The current result set
|
||||
* @param currentRow Current position of the result set
|
||||
* @return the mapped object at the cursor position
|
||||
* @throws SQLException
|
||||
* @throws SQLException if interactions with the current result set fail
|
||||
*/
|
||||
protected abstract T readCursor(ResultSet rs, int currentRow) throws SQLException;
|
||||
|
||||
|
||||
@@ -16,15 +16,6 @@
|
||||
|
||||
package org.springframework.batch.item.database;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.jdbc.datasource.ConnectionProxy;
|
||||
import org.springframework.jdbc.datasource.DataSourceUtils;
|
||||
import org.springframework.jdbc.datasource.SmartDataSource;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.MethodInvoker;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
@@ -35,6 +26,16 @@ import java.sql.SQLException;
|
||||
import java.sql.SQLFeatureNotSupportedException;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.jdbc.datasource.ConnectionProxy;
|
||||
import org.springframework.jdbc.datasource.DataSourceUtils;
|
||||
import org.springframework.jdbc.datasource.SmartDataSource;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.MethodInvoker;
|
||||
|
||||
/**
|
||||
* Implementation of {@link SmartDataSource} that is capable of keeping a single
|
||||
* JDBC Connection which is NOT closed after each use even if
|
||||
@@ -105,6 +106,8 @@ public class ExtendedConnectionDataSourceProxy implements SmartDataSource, Initi
|
||||
/**
|
||||
* Constructor that takes as a parameter with the {@link DataSource} to be
|
||||
* wrapped.
|
||||
*
|
||||
* @param dataSource DataSource to be used
|
||||
*/
|
||||
public ExtendedConnectionDataSourceProxy(DataSource dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
|
||||
@@ -129,6 +129,8 @@ public class HibernateItemReaderHelper<T> implements InitializingBean {
|
||||
|
||||
/**
|
||||
* Open appropriate type of hibernate session and create the query.
|
||||
*
|
||||
* @return a Hibernate Query
|
||||
*/
|
||||
public Query createQuery() {
|
||||
|
||||
@@ -174,6 +176,8 @@ public class HibernateItemReaderHelper<T> implements InitializingBean {
|
||||
* Scroll through the results up to the item specified.
|
||||
*
|
||||
* @param cursor the results to scroll over
|
||||
* @param itemIndex index to scroll to
|
||||
* @param flushInterval the number of items to scroll past before flushing
|
||||
*/
|
||||
public void jumpToItem(ScrollableResults cursor, int itemIndex, int flushInterval) {
|
||||
for (int i = 0; i < itemIndex; i++) {
|
||||
|
||||
@@ -122,8 +122,8 @@ public class HibernateItemWriter<T> implements ItemWriter<T>, InitializingBean {
|
||||
* Do perform the actual write operation using Hibernate's API.
|
||||
* This can be overridden in a subclass if necessary.
|
||||
*
|
||||
* @param items
|
||||
* the list of items to use for the write
|
||||
* @param sessionFactory Hibernate SessionFactory to be used
|
||||
* @param items the list of items to use for the write
|
||||
*/
|
||||
protected void doWrite(SessionFactory sessionFactory, List<? extends T> items) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
|
||||
@@ -29,6 +29,7 @@ public interface ItemSqlParameterSourceProvider<T> {
|
||||
* Provide parameter values in an {@link SqlParameterSource} based on values from
|
||||
* the provided item.
|
||||
* @param item the item to use for parameter values
|
||||
* @return parameters extracted from the item
|
||||
*/
|
||||
SqlParameterSource createSqlParameterSource(T item);
|
||||
|
||||
|
||||
@@ -23,14 +23,14 @@ import org.springframework.ldap.core.LdapAttributes;
|
||||
*
|
||||
* @author Keith Barlow
|
||||
*
|
||||
* @param <T>
|
||||
* @param <T> type the record will be mapped to
|
||||
*/
|
||||
public interface RecordMapper<T> {
|
||||
|
||||
/**
|
||||
* Maps an {@link LdapAttributes LdapAttributes} object to the specified type.
|
||||
*
|
||||
* @param attributes
|
||||
* @param attributes attributes
|
||||
* @return object of type T
|
||||
*/
|
||||
T mapRecord(LdapAttributes attributes);
|
||||
|
||||
@@ -154,20 +154,24 @@ public abstract class AbstractItemCountingItemStreamItemReader<T> extends Abstra
|
||||
maxItemCount = executionContext.getInt(getExecutionContextKey(READ_COUNT_MAX));
|
||||
}
|
||||
|
||||
int itemCount = 0;
|
||||
if (executionContext.containsKey(getExecutionContextKey(READ_COUNT))) {
|
||||
int itemCount = executionContext.getInt(getExecutionContextKey(READ_COUNT));
|
||||
|
||||
if (itemCount < maxItemCount) {
|
||||
try {
|
||||
jumpToItem(itemCount);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new ItemStreamException("Could not move to stored position on restart", e);
|
||||
}
|
||||
}
|
||||
currentItemCount = itemCount;
|
||||
|
||||
itemCount = executionContext.getInt(getExecutionContextKey(READ_COUNT));
|
||||
}
|
||||
else if(currentItemCount > 0) {
|
||||
itemCount = currentItemCount;
|
||||
}
|
||||
|
||||
if (itemCount > 0 && itemCount < maxItemCount) {
|
||||
try {
|
||||
jumpToItem(itemCount);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new ItemStreamException("Could not move to stored position on restart", e);
|
||||
}
|
||||
}
|
||||
|
||||
currentItemCount = itemCount;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ public interface Poller<T> {
|
||||
*
|
||||
* @param callable a {@link Callable} to use to retrieve a result
|
||||
* @return a future which itself can be used to get the result
|
||||
* @throws java.lang.Exception
|
||||
* @throws java.lang.Exception allows for checked exceptions
|
||||
*/
|
||||
Future<T> poll(Callable<T> callable) throws Exception;
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ public class RepeatOperationsInterceptor implements MethodInterceptor {
|
||||
/**
|
||||
* Setter for the {@link RepeatOperations}.
|
||||
*
|
||||
* @param batchTempate
|
||||
* @param batchTempate template to be used
|
||||
* @throws IllegalArgumentException if the argument is null.
|
||||
*/
|
||||
public void setRepeatOperations(RepeatOperations batchTempate) {
|
||||
|
||||
Reference in New Issue
Block a user