This is what I thought however not the behavior I am seeing. The two jobs do contain unique job parameters, in fact a new Date() is set guaranteeing uniquness.
Code:
// Execute the batch Job
jobLauncher.run(batchExportJob, new JobParametersBuilder()
.addDate(BatchProcessingMessageCodes.DATE_TIME_STAMP, new Date())
.addString(BatchProcessingMessageCodes.EXPORT_FILE_NAME, parameters.getExportFileName())
.addString(BatchProcessingMessageCodes.FAILURE_FILE_NAME, parameters.getFailureFileName())
.addString(BatchProcessingMessageCodes.HEADER_FILE_PROCESS_DATE, parameters.getProcessDate())
.addString(BatchProcessingMessageCodes.EXTENSION, BatchProcessingMessageCodes.CSV_FILE_EXTENSION) .addString(BatchProcessingMessageCodes.WHERE_CLAUSE, parameters.getWhereClause())
.addString(BatchProcessingMessageCodes.ENCRYPTION_KEY, BatchProcessingMessageCodes.ENCRYPTION_TRANSACTION_EXPORT).toJobParameters());
Code:
<bean id="jobLauncher"
class="org.springframework.batch.core.launch.support.SimpleJobLauncher" >
<property name="jobRepository" ref="jobRepository" />
</bean>
Code:
<batch:job id="batchExportJob" >
<batch:step id="findTransactionsReadyForExport" >
<batch:tasklet transaction-manager="jpaTransactionManager" >
<batch:chunk reader="transactionReader" processor="transactionProcessor"
writer="transactionWriter" commit-interval="100" >
</batch:chunk>
<batch:listeners>
<batch:listener class="net.companyname.batch.listener.SkipCheckingListener" />
<batch:listener ref="exportTransactionItemFailedLoggerListener" />
<batch:listener ref="exportTransactionFileHeaderCallback" />
<batch:listener ref="exportTransactionFileFooterCallback" />
</batch:listeners>
</batch:tasklet>
<batch:fail on="FAILED" exit-code="FAILED" />
<batch:next on="*" to="updateStatus" />
</batch:step>
<batch:step id="updateStatus">
<batch:tasklet transaction-manager="jpaTransactionManager" ref="updateStatuses">
<batch:listeners>
<batch:listener ref="exportTransactionItemFailedLoggerListener" />
</batch:listeners>
</batch:tasklet>
<batch:fail on="FAILED" exit-code="FAILED" />
<batch:end on="*" exit-code="COMPLETED" />
</batch:step>
</batch:job>
<bean id="transactionReader"
class="org.springframework.batch.item.database.JdbcCursorItemReader"
scope="step">
<property name="dataSource" ref="dataSource" />
<property name="sql"
value="select t.id from transaction t join batch b on t.batch_id = b.id #{jobParameters[EXPORT_TRANSACTION_WHERE_CLAUSE]}" />
<property name="rowMapper">
<bean class="net.targetgroup.accounts.base.batch.mapper.IdRowMapper" />
</property>
</bean>
<bean id="transactionProcessor"
class="net.targetgroup.accounts.base.batch.processor.ExportTransactionProcessor">
<property name="failListener" ref="exportTransactionItemFailedLoggerListener" />
</bean>
<bean id="transactionWriter"
class="net.targetgroup.accounts.base.batch.writer.ExportTransactionWriter">
<property name="delegate">
<bean class="org.springframework.batch.item.file.FlatFileItemWriter">
<property name="lineAggregator">
<bean class="org.springframework.batch.item.file.transform.DelimitedLineAggregator">
<property name="delimiter" value=","/>
<property name="fieldExtractor">
<bean class="net.targetgroup.accounts.base.batch.BeanWrapperFieldExtractor">
<property name="names" value="some,comma,delimited,values"/>
</bean>
</property>
</bean>
</property>
<property name="headerCallback" ref="exportTransactionFileHeaderCallback" />
<property name="footerCallback" ref="exportTransactionFileFooterCallback" />
</bean>
</property>
</bean>
You can see that I pass a new Date() as a parameter and so the two jobs are different. By the time the code gets to the header the first thread has had its parameters replaced by the second. I have put breakpoints on and as yet have not identified the point they get replaced. I can see that the spring code does create a new instance but then gets overwritten further on.
It is worth mentioning that I get the stepExecution in the header and processor by implementing StepExecutionListener and use the beforeStep(StepExecution stepExecution) to set it.
Apologies for the long post!