Home > Enterprise >  JdbcPagingItemReader with sort key crashes in multithreaded step for empty query if I do not have se
JdbcPagingItemReader with sort key crashes in multithreaded step for empty query if I do not have se

Time:01-26

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.

  • Related