Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Batch -@BeforeStep not getting invoked in Partitioner

We are trying to implement a batch job using spring batch partitioning.In this in "step 2" is a partitioned step where I need some data from step 1 for processing.I used StepExecutionContext which will be promoted to job Execution Context at step1 to store this data.

I tried to use @BeforeStep annotation in partitioner class to get the stepExecutionContext from which I can extract the data stored previously and put it in ExecutionContext of the partitioner .But the method with @BeforeStep annotation is not getting invoked in the partitioner.

Is there any other way to achieve this.

Partitioner Implementation

public class NtfnPartitioner implements Partitioner {

    private int index = 0;
    String prev_job_time  = null;
    String curr_job_time  = null;

    private StepExecution stepExecution ;
    ExecutionContext executionContext ;

    @Override
    public Map<String, ExecutionContext> partition(int gridSize)
    {

           System.out.println("Entered Partitioner");
           List<Integer> referencIds = new ArrayList<Integer>();
           for (int i = 0; i < gridSize;i++) {
            referencIds.add(index++);
           }
           Map<String, ExecutionContext> results = new LinkedHashMap<String,ExecutionContext>();
          for (int referencId : referencIds) {
            ExecutionContext context = new ExecutionContext();
            context.put("referenceId", referencId);
            context.put(NtfnConstants.PREVIOUS_JOB_TIME, prev_job_time);
            context.put(NtfnConstants.JOB_START_TIME, curr_job_time);
            results.put("partition." + referencId, context);
          }
            return results;
        }

    @BeforeStep
    public void beforeStep(StepExecution stepExecution) {
        // TODO Auto-generated method stub
          System.out.println("Entered Before step in partion");
          JobExecution jobExecution = stepExecution.getJobExecution();
          ExecutionContext jobContext = jobExecution.getExecutionContext();
          System.out.println("ExecutionContext"+jobContext);
          String prev_job_time  = (String) jobContext.get(NtfnConstants.PREVIOUS_JOB_TIME);
          String curr_job_time  = (String) jobContext.get(NtfnConstants.JOB_START_TIME);


    }
like image 660
Dobby Avatar asked Feb 06 '14 08:02

Dobby


1 Answers

The bean should be step scoped.

Java, annotate class:

@StepScope

XML, in bean definition:

scope="step"

Also look at this answer regarding proxied bean (not sure if this applies to you since no other code than the partitioner was provided). In this case you can still add your partitioner as a listener explicitly during step building:

@Autowired
private NtfnPartitioner partitioner;    

...

final Step masterStep = stepBuilderFactory.get("master")
                    .listener(partitioner)
                    .partitioner("slave", partitioner)
                    .step(slave)
                    ...

Or if your partitioner is not bean (e.g. you are creating it based on something dynamic), you can still add it as a listener:

final NtfnPartitioner partitioner = new NtfnPartitioner();    
final Step masterStep = stepBuilderFactory.get("master")
                    .listener(partitioner)
                    .partitioner("slave", partitioner)
                    .step(slave)
                    ...
like image 198
ezpz Avatar answered Nov 11 '22 22:11

ezpz