12

I need to store Job ExecutionId as one of the fields of Entity. (I am using JpaItemWriter) One of topic here explains from StepExcecution, I can get StepContext -> JobExecution. In that case how to get StepExecution?

(I have no need to pass any data from one step to another, all I need is JobExecuionId)

Thanks for help, Muneer Ahmed

Muneer Ahmed Syed
  • 161
  • 1
  • 2
  • 6

7 Answers7

7

I would suggest you use a processor that updates your Entity with value. If your processors directly implements ItemProcessor<T> then you will not automatically get the StepExecution. To get the StepExecution, do 1 of the following; - implement StepExecutionListener and set it as a variable from the beforeStep method - create a method called [something](StepExecution execution) and annotate with @BeforeStep

once you've injected the StepExecution via a listener, you can then get the jobExecutionId and set it into your entity

public class MyEntityProcessor implements ItemProcessor<MyEntity, MyEntity> {

private long jobExecutionId;

@BeforeStep
public void beforeStep(StepExecution stepExecution) {
    jobExecutionId = stepExecution.getJobExecutionId();
}

@Override
public MyEntity process(MyEntity item) throws Exception {
    //set the values
    item.setJobExecutionId(jobExecutionId);
    //continue
    return item;
}

}
incomplete-co.de
  • 2,137
  • 18
  • 23
  • It is "complete code" contrary to your name ;-) . Thanks for your answer. Great help. – Muneer Ahmed Syed Jan 10 '13 at 18:12
  • 4
    could you post the spring context xml used to wire this bean. I'm following the same pattern but it seems the beforeStep() is not being called. Do you need to explicity register the MyEntityProcessor bean as a listener somewhere? – emeraldjava Jan 14 '14 at 12:08
  • I used this solution for this problem and it worked, but it turns out it is not thread safe. If you multiple jobs running they can get the wrong job id which is a serious problem. – BrianC Jun 13 '14 at 20:25
  • You have to set this processor as a listener... so for me this solution doesn't smell well... Better set it in another class who is dedicated to this purpose – Philippe Feb 26 '18 at 14:21
5

We can set the scope as job using @Scope("job") of Itemprocessor and can easly get JobExecution using @Value("#{jobExecution}") expression as below.

@Service
@Scope("job")
public class XsltTransformer implements ItemProcessor<Record, Record> {

@Value("#{jobExecution}")
private JobExecution jobExecution;

}
Awanish Kumar
  • 640
  • 8
  • 15
  • 2
    I ran into issues with this because the scope of a item processor is "step". Instead I retrieved the stepExecution and got the job execution by calling stepExecution.getJobExecution(). – Tony Edwards Nov 11 '16 at 15:42
3

Scope as job using @Scope("job") of and get JobExecution using @Value("#{jobExecution}")

FelixSFD
  • 6,052
  • 10
  • 43
  • 117
Rahul Raj
  • 107
  • 1
  • 2
3

You have to add the following:

@Value("#{stepExecution.jobExecution}")

private JobExecution jobExecution;

in your reader Writer or processor. It will certainly work.

Anastasios Selmani
  • 3,579
  • 3
  • 32
  • 48
1

If you want to use @BeforeStep in MyEntityProcessor you must declare it like a listener

<batch:listeners>
 <batch:listener ref="myEntityProcessor" />
</batch:listeners>
nekperu15739
  • 3,311
  • 2
  • 26
  • 25
1

I had same issue. I used @StepScope in my processor Implementation

@Value("#{stepExecution.jobExecution}")
private JobExecution jobExecution;
0

I had a similar issue when I wanted to get the JobInstanceID. Below is how I got StepExecution and then retreived JobExecution. I hope this helps.

public class FoobarItemProcessor implements ItemProcessor<Foobar, Foobar> {

private JobExecution jobExecution;

@BeforeStep
public void beforeStep(StepExecution stepExecution) {
    jobExecution = stepExecution.getJobExecution();
}
Tony Edwards
  • 431
  • 1
  • 7
  • 18