0

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.

Community
  • 1
  • 1
emeraldjava
  • 10,894
  • 26
  • 97
  • 170
  • Where are you trying to include this information about the current job/step? – Joshua Moore Dec 17 '13 at 11:56
  • I have a feature request that says the user wants to know how many rows are inserted to the various DB during the same job. There are a few ways to do this but the current option i'm looking at is to use the spring batch job id, which would allow me to link the report back to the spring batch admin. – emeraldjava Dec 17 '13 at 12:00
  • 1
    I think this may [answer][1] your question. Simply put, it's not possible. [1]: http://stackoverflow.com/questions/17149302/how-to-get-job-id-using-spring-expression-language – Joshua Moore Dec 17 '13 at 12:13

2 Answers2

1

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>
Michael Minella
  • 20,843
  • 4
  • 55
  • 67
1

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>
Haim Raman
  • 11,508
  • 6
  • 44
  • 70