emeraldjava
emeraldjava

Reputation: 11190

Accessing Spring Batch Job/Step details via the generic query provider

I'm setting up a batch job that moves data between three databases. I am planning on using the out of the box spring batch classes to handle the query from the first database, but i want to include details of the current job/step in the extract. The example spring config might look like this

<bean id="jdbcPagingItemReader" class="org.springframework.batch.item.database.JdbcPagingItemReader">   <property name="dataSource" ref="dataSource"/>
    <property name="pageSize" value="1000"/>
    <property name="fetchSize" value="100"/>
    <property name="queryProvider">
        <bean class="org.springframework.batch.item.database.support.HsqlPagingQueryProvider">
            <property name="selectClause" value="select id, bar"/>
                <property name="fromClause" value="foo"/>
                <property name="sortKeys">

Is there a way via groovy or SpEL to access the current JobExecution? I had found this thread on access-spring-batch-job-definition but is assumes custom code.

Upvotes: 0

Views: 2105

Answers (2)

Haim Raman
Haim Raman

Reputation: 12023

The write count exists on the step context (StepExecution.getWriteCount()) so first you need to promote it to the JobExecutionContext.

I suggest using a Step listener with @AfterStep annotation for this

@Component 
public class PromoteWriteCountToJobContextListener implements StepListener {
    @AfterStep
    public ExitStatus afterStep(StepExecution stepExecution){
        int writeCount = stepExecution.getWriteCount();
        stepExecution.getJobExecution().getExecutionContext()
        .put(stepExecution.getStepName()+".writeCount", writeCount);
        return stepExecution.getExitStatus();
    }   
}

Every step that perform the inserts will be added with this listner

<batch:step id="readFromDB1WrietToDB2" next="readFroDB2WrietToDB3">
            <batch:tasklet transaction-manager="transactionManager">
                <batch:chunk reader="reader" writer="writter" />
            </batch:tasklet>
            <batch:listeners>
                <batch:listener ref="promoteWriteCountToJobContextListener"/>
            </batch:listeners>
    </batch:step>       
    <batch:step id="readFromDB2WrietToDB3" next="summerizeWrites">
            <batch:tasklet transaction-manager="transactionManager">
                <batch:chunk reader="reader"  writer="writter" />
            </batch:tasklet>
            <batch:listeners>
                <batch:listener ref="promoteWriteCountToJobContextListener"/>
            </batch:listeners>
    </batch:step>

You can use log4j to write the results to log within the Step Listener, or you can use the saved values in a future step. You need to use SpEL expression to read it, to Use SpEL expression you need to set the Writter/Tasklet at scope="step"

<batch:step id="summerizeWrites">
        <batch:tasklet id="summerizeCopyWritesTaskelt"">
            <bean class="Tasklet" scope="step">
                <property name="writeCountsList">   
                    <list>
                        <value>#{jobExecutionContext['readFromDB1WrietToDB2.writeCount']}</value>
                        <value>#{jobExecutionContext['readFromDB2WrietToDB3.writeCount']}</value>
                    </list>
                </property>
            </bean>
        </batch:tasklet>

Upvotes: 1

Michael Minella
Michael Minella

Reputation: 21453

Your configuration is cut off at the sortKeys entry so I'm not 100% sure what you are attempting to accomplish. That being said, using step scope, you can inject the StepExecution which has a reference to the JobExecution. Getting the JobExecution would look something like this:

<bean id="jdbcPagingItemReader" class="org.springframework.batch.item.database.JdbcPagingItemReader">
    …
    <property id="jobExecution" value="#{stepExecution.jobExecution}"/>
</bean>

Upvotes: 1

Related Questions