Reputation: 96394
I have a job that has to run multiple times with different job parameters. I want to set up a JdbcCursorItemReader to perform a query for the job, the itemReader is configured like this:
<bean id="tpsItemReader"
class="org.springframework.batch.item.database.JdbcCursorItemReader">
<property name="dataSource" ref="myDataSource"/>
<property name="sql" value="#{sqlQueries['tps.findStuffforSomeSubset']}"/>
<property name="preparedStatementSetter">
<bean class="com.initech.reports.tps.ParameterSetter">
<!-- can't hardcode this, I want a job parameter here -->
<constructor-arg value="A"/>
</bean>
</property>
<property name="rowMapper">
<bean class="com.initech.reports.tps.CustomerRowMapper"/>
</property>
</bean>
and the job is configured like this:
<batch:job id="tpsReportJob">
<batch:step id="tpsReportJob.generateReport">
<batch:tasklet>
<batch:chunk reader="tpsItemReader"
processor="tpsItemProcessor"
writer="tpsItemWriter" commit-interval="100000"/>
</batch:tasklet>
</batch:step>
</batch:job>
The parameterSetter is pretty minimal:
package com.initech.reports.tps;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import org.springframework.jdbc.core.PreparedStatementSetter;
public class ParameterSetter implements PreparedStatementSetter {
private final String x;
public ParameterSetter(String x) {this.x = x;}
@Override
public void setValues(PreparedStatement ps) throws SQLException {
ps.setString(1, x);
}
}
This is using spring-batch 2.1.8.
How do I get the job parameter into the query?
I think I'm close, I tried changing the parameter setter config to:
<bean class="com.initech.reports.tps.ParameterSetter">
<constructor-arg value="#{jobParameters['myParam']}"/>
</bean>
but I get this error:
Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 0): Field or property 'jobParameters' cannot be found on object of type 'org.springframework.beans.factory.config.BeanExpressionContext'
at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:208)
at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:72)
at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:52)
at org.springframework.expression.spel.ast.SpelNodeImpl.getValue(SpelNodeImpl.java:93)
at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:88)
at org.springframework.context.expression.StandardBeanExpressionResolver.evaluate(StandardBeanExpressionResolver.java:139)
... 51 more
I found a very similar question, the difference between that one and this is that I don't have a reader class to annotate, I just have the xml entry because I'd like to avoid having to create my own itemReader. (I could try overriding the jdbcCursorItemReader class just to be able to annotate it...)
Upvotes: 4
Views: 12900
Reputation: 96394
All it took was adding the scope attribute onto the parameterSetter class:
<bean class="com.initech.reports.tps.ParameterSetter"
scope="step">
<constructor-arg value="#{jobParameters['myParam']}"/>
</bean>
Upvotes: 4