I am working in a Spring batch application using Spring batch version 4.3.5. I was getting below error in JdbcPagingItemReader when there is no record. It is to mention that I am using this reader in a multithreaded step.
org.springframework.dao.InvalidDataAccessApiUsageException: No value supplied for the SQL parameter '_PIN_SEQ_ID': No value registered for key '_PIN_SEQ_ID' at org.springframework.jdbc.core.namedparam.NamedParameterUtils.buildValueArray(NamedParameterUtils.java:354) at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.getPreparedStatementCreator(NamedParameterJdbcTemplate.java:418) at org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate.getPreparedStatementCreator(NamedParameterJdbcTemplate.java:392)
I have below code for reader which is giving above error until I added reader.setSaveState(false);
public JdbcPagingItemReader<BatchUserHistoryMVDO> processJobReader(
@Value("#{jobExecutionContext[batchId]}") long batchId) {
final JdbcPagingItemReader<BatchUserHistoryMVDO> reader = new JdbcPagingItemReader<>();
final BatchUserHistoryMVMapper userHistoryMVMapper = new BatchUserHistoryMVMapper();
reader.setDataSource(this.dataSource.getSecondaryDataSource());
reader.setFetchSize(this.configProperties.getProcessPageSize());
reader.setPageSize(this.configProperties.getProcessPageSize());
reader.setRowMapper(userHistoryMVMapper);
reader.setQueryProvider(createQuery());
Map<String, Object> parameters = new HashMap<>();
parameters.put("id", batchId);
reader.setParameterValues(parameters);
return reader;
}
private AbstractSqlPagingQueryProvider createQuery() {
final Map<String, Order> sortKeys = new HashMap<>();
sortKeys.put("PIN_SEQ_ID", Order.ASCENDING);
final AbstractSqlPagingQueryProvider queryProvider = new
OraclePagingQueryProvider();
queryProvider.setSelectClause("*");
queryProvider.setFromClause("from POA01.BATCH_USER_HISTORY_MV where batch_id = :id");
queryProvider.setSortKeys(sortKeys);
return queryProvider;
}
After I added reader.setSaveState(false), batch is getting completed without any issue. My question is what setSaveState(false) doing in this scenerio? Why my batch was failing with sort key crashes if I do not have setSaveState(false)?
CodePudding user response:
It is to mention that I am using this reader in a multithreaded step. [...] After I added reader.setSaveState(false), batch is getting completed without any issue
From the Javadoc of JdbcPagingItemReader
:
The implementation is thread-safe in between calls to `#open(ExecutionContext)`,
but remember to use `saveState=false` if used in a multi-threaded client
(no restart available).
The saveState
flag instructs the reader to save the execution context or not. When running the step in a multi-threaded mode, threads can alter each other information saved in the execution context (the read count for example). Therefore, manipulating the execution context in a multi-threaded step is not recommended.