I have a spring batch job where I need to get a value from database in a step and use that value in a reader in an other step . but I m getting an error saying :
'Invalid property 'id' of bean class [org.springframework.batch.core.scope.context.StepContext]: Bean property 'id' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?'
here I will put only the relevant part of my files to be clear , if need extra infos I can add it , thanks
xml config file:
<bean id="setter" class="fat.IdSetter" scope="step">
<property name="id" value="#{stepExecutionContext([id])}"></property>
</bean>
<bean id="reader"
class="org.springframework.batch.item.database.JdbcCursorItemReader" >
<property name="dataSource" ref="dataSource" />
<property name="sql" value="SELECT * FROM TABLE WHERE ID = ?" />
<property name="rowMapper">
<bean class="fat.RowMapper"></bean>
</property>
<property name="preparedStatementSetter" ref="setter"></property>
</bean>
<batch:job id="job">
<batch:step id="getId" next="loopStep">
<batch:tasklet ref="getId"></batch:tasklet>
</batch:step>
<batch:step id="loopStep">
<batch:tasklet>
<batch:chunk reader="reader" processor="processor"
writer="xmlWriter" commit-interval="1000">
</batch:chunk>
<batch:listeners>
<batch:listener ref="footerCallBack"></batch:listener>
<batch:listener ref="headerCallBack"></batch:listener>
</batch:listeners>
</batch:tasklet>
</batch:step>
</batch:job>
<bean id="getId" class="fat.GetId" >
<property name="restCall" ref="restCall"></property>
</bean>
the tasklet where I get the value of id :
public class GetId implements Tasklet {
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
// here I call my web service to get data and put it in a Long variable named id
chunkContext.getStepContext().getStepExecution().getJobExecution().getExecutionContext().put("id",
id);
return RepeatStatus.FINISHED;
}
}
the prepared statement setter for id class:
public class IdSetter implements PreparedStatementSetter {
private Long id;
@Override
public void setValues(PreparedStatement ps) throws SQLException {
ps.setLong(1 , id);
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
I think the error because it didn t find the id parameter in the stepExecutionContext , any help is appreciated.
Your tasklet GetId
puts the id
in the job execution context. So your reader can get it from there as follows:
<bean id="reader" class="org.springframework.batch.item.database.JdbcCursorItemReader" scope="step" >
<property name="dataSource" ref="dataSource" />
<property name="sql" value="SELECT * FROM TABLE WHERE ID = #{jobExecutionContext[id]}" />
<property name="rowMapper">
<bean class="fat.RowMapper"></bean>
</property>
<!-- <property name="preparedStatementSetter" ref="setter"></property> --> // This is not needed
</bean>
Note that the reader should step scoped. With that, you don't need the bean named setter
.
Another option is to pass the id as a job parameter and use it in the reader (See example here).