Class AbstractCursorItemReader<T>
- All Implemented Interfaces:
ItemReader<T>
,ItemStream
,ItemStreamReader<T>
,org.springframework.beans.factory.InitializingBean
- Direct Known Subclasses:
JdbcCursorItemReader
,StoredProcedureItemReader
Abstract base class for any simple item reader that opens a database cursor and continually retrieves the next row in the ResultSet.
By default the cursor will be opened using a separate connection. The ResultSet for the cursor is held open regardless of commits or roll backs in a surrounding transaction. Clients of this reader are responsible for buffering the items in the case that they need to be re-presented on a rollback. This buffering is handled by the step implementations provided and is only a concern for anyone writing their own step implementations.
There is an option (setUseSharedExtendedConnection(boolean)
that will share
the connection used for the cursor with the rest of the step processing. If you set
this flag to true
then you must wrap the DataSource in a
ExtendedConnectionDataSourceProxy
to prevent the connection from being closed
and released after each commit performed as part of the step processing. You must also
use a JDBC driver supporting JDBC 3.0 or later since the cursor will be opened with the
additional option of 'HOLD_CURSORS_OVER_COMMIT' enabled.
Each call to AbstractItemCountingItemStreamItemReader.read()
will attempt to map the row at the current position in the
ResultSet. There is currently no wrapping of the ResultSet to suppress calls to next().
However, if the RowMapper (mistakenly) increments the current row, the next call to
read will verify that the current row is at the expected position and throw a
DataAccessException if it is not. The reason for such strictness on the ResultSet is
due to the need to maintain control for transactions and restartability. This ensures
that each call to AbstractItemCountingItemStreamItemReader.read()
returns the ResultSet at the correct row, regardless
of rollbacks or restarts.
ExecutionContext
: The current row is returned as restart data, and when
restored from that same data, the cursor is opened and the current row set to the value
within the restart data. See setDriverSupportsAbsolute(boolean)
for improving
restart performance.
Calling close on this ItemStream
will cause all resources it is currently using
to be freed. (Connection, ResultSet, etc). It is then illegal to call AbstractItemCountingItemStreamItemReader.read()
again until it has been re-opened.
Known limitation: when used with Derby setVerifyCursorPosition(boolean)
needs
to be false
because ResultSet.getRow()
call used for cursor
position verification is not available for 'TYPE_FORWARD_ONLY' result sets.
Subclasses are inherently not thread-safe.
- Author:
- Lucas Ward, Peter Zozom, Robert Kasanicky, Thomas Risberg, Michael Minella, Mahmoud Ben Hassine
-
Field Summary
Modifier and TypeFieldDescriptionprotected final org.apache.commons.logging.Log
Logger available to subclassesprotected ResultSet
static final int
-
Constructor Summary
-
Method Summary
Modifier and TypeMethodDescriptionvoid
Assert that mandatory properties are set.protected void
Prepare the given JDBC Statement (or PreparedStatement or CallableStatement), applying statement settings such as fetch size, max rows, and query timeout.protected abstract void
cleanupOnClose
(Connection connection) Clean up resources.protected void
doClose()
Close the cursor and database connection.protected void
doOpen()
Execute the statement to open the cursor.protected T
doRead()
Read next row and map it to item, verify cursor position ifsetVerifyCursorPosition(boolean)
is true.Public getter for the data source.protected org.springframework.jdbc.support.SQLExceptionTranslator
Creates a default SQLErrorCodeSQLExceptionTranslator for the specified DataSource if none is set.abstract String
getSql()
protected void
handleWarnings
(Statement statement) Throw a SQLWarningException if we're not ignoring warnings, else log the warnings (at debug level).protected void
boolean
protected void
jumpToItem
(int itemIndex) UseResultSet.absolute(int)
if possible, otherwise scroll by callingResultSet.next()
.protected abstract void
openCursor
(Connection con) protected abstract T
readCursor
(ResultSet rs, int currentRow) Read the cursor and map to the type of object this reader should return.void
setConnectionAutoCommit
(boolean autoCommit) Set whether "autoCommit" should be overridden for the connection used by the cursor.void
setDataSource
(DataSource dataSource) Public setter for the data source for injection purposes.void
setDriverSupportsAbsolute
(boolean driverSupportsAbsolute) Indicate whether the JDBC driver supports setting the absolute row on aResultSet
.void
setFetchSize
(int fetchSize) Gives the JDBC driver a hint as to the number of rows that should be fetched from the database when more rows are needed for thisResultSet
object.void
setIgnoreWarnings
(boolean ignoreWarnings) Set whether SQLWarnings should be ignored (only logged) or exception should be thrown.void
setMaxRows
(int maxRows) Sets the limit for the maximum number of rows that anyResultSet
object can contain to the given number.void
setQueryTimeout
(int queryTimeout) Sets the number of seconds the driver will wait for aStatement
object to execute to the given number of seconds.void
setUseSharedExtendedConnection
(boolean useSharedExtendedConnection) Indicate whether the connection used for the cursor should be used by all other processing thus sharing the same transaction.void
setVerifyCursorPosition
(boolean verifyCursorPosition) Allow verification of cursor position after current row is processed by RowMapper or RowCallbackHandler.protected org.springframework.dao.DataAccessException
translateSqlException
(String task, String sql, SQLException ex) Methods inherited from class org.springframework.batch.item.support.AbstractItemCountingItemStreamItemReader
close, getCurrentItemCount, isSaveState, open, read, setCurrentItemCount, setMaxItemCount, setSaveState, update
Methods inherited from class org.springframework.batch.item.ItemStreamSupport
getExecutionContextKey, getName, setExecutionContextName, setName
-
Field Details
-
log
protected final org.apache.commons.logging.Log logLogger available to subclasses -
VALUE_NOT_SET
public static final int VALUE_NOT_SET- See Also:
-
rs
-
-
Constructor Details
-
AbstractCursorItemReader
public AbstractCursorItemReader()
-
-
Method Details
-
afterPropertiesSet
Assert that mandatory properties are set.- Specified by:
afterPropertiesSet
in interfaceorg.springframework.beans.factory.InitializingBean
- Throws:
IllegalArgumentException
- if either data source or SQL properties not set.Exception
-
setDataSource
Public setter for the data source for injection purposes.- Parameters:
dataSource
-DataSource
to be used
-
getDataSource
Public getter for the data source.- Returns:
- the dataSource
-
applyStatementSettings
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- Parameters:
stmt
-PreparedStatement
to be configured- Throws:
SQLException
- if interactions with provided stmt fail- See Also:
-
getExceptionTranslator
protected org.springframework.jdbc.support.SQLExceptionTranslator getExceptionTranslator()Creates a default SQLErrorCodeSQLExceptionTranslator for the specified DataSource if none is set.- Returns:
- the exception translator for this instance.
-
translateSqlException
protected org.springframework.dao.DataAccessException translateSqlException(String task, String sql, SQLException ex) -
handleWarnings
protected void handleWarnings(Statement statement) throws org.springframework.jdbc.SQLWarningException, SQLException Throw a SQLWarningException if we're not ignoring warnings, else log the warnings (at debug level).- Parameters:
statement
- the current statement to obtain the warnings from, if there are any.- Throws:
SQLException
- if interaction with provided statement fails.org.springframework.jdbc.SQLWarningException
- See Also:
-
SQLWarningException
-
setFetchSize
public void setFetchSize(int fetchSize) Gives the JDBC driver a hint as to the number of rows that should be fetched from the database when more rows are needed for thisResultSet
object. If the fetch size specified is zero, the JDBC driver ignores the value.- Parameters:
fetchSize
- the number of rows to fetch- See Also:
-
setMaxRows
public void setMaxRows(int maxRows) Sets the limit for the maximum number of rows that anyResultSet
object can contain to the given number.- Parameters:
maxRows
- the new max rows limit; zero means there is no limit- See Also:
-
setQueryTimeout
public void setQueryTimeout(int queryTimeout) Sets the number of seconds the driver will wait for aStatement
object to execute to the given number of seconds. If the limit is exceeded, anSQLException
is thrown.- Parameters:
queryTimeout
- seconds the new query timeout limit in seconds; zero means there is no limit- See Also:
-
setIgnoreWarnings
public void setIgnoreWarnings(boolean ignoreWarnings) Set whether SQLWarnings should be ignored (only logged) or exception should be thrown.- Parameters:
ignoreWarnings
- if TRUE, warnings are ignored
-
setVerifyCursorPosition
public void setVerifyCursorPosition(boolean verifyCursorPosition) Allow verification of cursor position after current row is processed by RowMapper or RowCallbackHandler. Default value is TRUE.- Parameters:
verifyCursorPosition
- if true, cursor position is verified
-
setDriverSupportsAbsolute
public void setDriverSupportsAbsolute(boolean driverSupportsAbsolute) Indicate whether the JDBC driver supports setting the absolute row on aResultSet
. It is recommended that this is set totrue
for JDBC drivers that supports ResultSet.absolute() as it may improve performance, especially if a step fails while working with a large data set.- Parameters:
driverSupportsAbsolute
-false
by default- See Also:
-
setConnectionAutoCommit
public void setConnectionAutoCommit(boolean autoCommit) Set whether "autoCommit" should be overridden for the connection used by the cursor. If not set, defaults to Connection / Datasource default configuration.- Parameters:
autoCommit
- value used forConnection.setAutoCommit(boolean)
.- Since:
- 4.0
-
getSql
-
doClose
Close the cursor and database connection. Make call to cleanupOnClose so sub classes can cleanup any resources they have allocated.- Specified by:
doClose
in classAbstractItemCountingItemStreamItemReader<T>
- Throws:
Exception
- Allows subclasses to throw checked exceptions for interpretation by the framework
-
cleanupOnClose
Clean up resources.- Parameters:
connection
- to the database- Throws:
Exception
- If unable to clean up resources
-
doOpen
Execute the statement to open the cursor.- Specified by:
doOpen
in classAbstractItemCountingItemStreamItemReader<T>
- Throws:
Exception
- Allows subclasses to throw checked exceptions for interpretation by the framework
-
initializeConnection
protected void initializeConnection() -
openCursor
-
doRead
Read next row and map it to item, verify cursor position ifsetVerifyCursorPosition(boolean)
is true.- Specified by:
doRead
in classAbstractItemCountingItemStreamItemReader<T>
- Returns:
- an item or
null
if the data source is exhausted - Throws:
Exception
- Allows subclasses to throw checked exceptions for interpretation by the framework
-
readCursor
Read the cursor and map to the type of object this reader should return. This method must be overridden by subclasses.- Parameters:
rs
- The current result setcurrentRow
- Current position of the result set- Returns:
- the mapped object at the cursor position
- Throws:
SQLException
- if interactions with the current result set fail
-
jumpToItem
UseResultSet.absolute(int)
if possible, otherwise scroll by callingResultSet.next()
.- Overrides:
jumpToItem
in classAbstractItemCountingItemStreamItemReader<T>
- Parameters:
itemIndex
- index of item (0 based) to jump to.- Throws:
Exception
- Allows subclasses to throw checked exceptions for interpretation by the framework
-