I have a batch job which reads from a database using HibernateCursorItemReader
, processes the results using a custom processor then commits to another database.
What I would like to show is how many items have been processed against total items to process.
I have tried implementing a custom JobExecutionListener
with @beforeJob
to get the row count from the first table which can then be compared
against the Job Execution
commits periodically.
Is there a better way than using a Job Execution
Listener. is it possible to get the total row count for the table on the first read, setting a value on the HibernateCursorItemReader
during initialization or something similar?
Job
<batch:job id="SomeLongJob" job-repository="jobRepository" restartable="true">
<batch:listeners>
<batch:listener ref="batchJobExecutionListener" />
</batch:listeners>
<batch:step id="first1">
<tasklet transaction-manager="hibernateTransactionManager">
<chunk reader="hibernateItemReader"
processor="batchCustomProcessor"
writer="hibernateItemWriter"
skip-limit="0"
commit-interval="10">
</chunk>
</tasklet>
</batch:step>
</batch:job>
Reader
<bean id="hibernateItemReader"
class="org.springframework.batch.item.database.HibernateCursorItemReader">
<property name="queryString" value="from MyTable" />
<property name="sessionFactory" ref="sessionFactory" />
</bean>
Before Job Starts get total items to process i.e. rows
BatchJobExecutionListener.class
public void beforeJob(JobExecution jobExecution) {
int total = yourDao.getTotalRows();
jobExecution.getExecutionContext().put("jobComplete", total);
}
During job execution retrieve total items and compare to read count
JobWrapper.class
...
private JobExecution jobE;
...
public Long getProgress() {
double jobComplete = (Double) jobE.getExecutionContext()
.get("jobComplete");
double reads = 0;
for (StepExecution step : jobE.getStepExecutions()) {
reads = reads + step.getReadCount();
}
return Math.round(reads / jobComplete * 100);
}