Spring batch late binding for stepExecutionContext not working

只愿长相守 提交于 2019-12-11 19:46:22

问题


I am using Spring batch application and want to use late binding for stepExecutionContext. I am facing issues in resolving my error.

Following is my reader which has sql property using late binding:

<bean id="itemReader_S4_JPolicy" class="com.aegonusa.etl.readers.JDBCItemReader" scope="step">
    <property name="jobParameters" ref="jobParameters" />
    <property name="dataSource" ref="readDataSource" />
    <property name="rowMapper">
    <bean class="com.aegonusa.etl.readers.ResultSetRowMapper" scope="step" />
    </property>
    <property name="sql"
        value="#{stepExecutionContext['readQuery']}"></property>
</bean>

I set this property ('readQuery') in following class:

public class StepListener implements StepExecutionListener {

.... ....

@Override
public void beforeStep(StepExecution execution) {
            String s = "select getdate();
    StepSynchronizationManager.getContext().setAttribute("readQuery", s);

..... } ..... }

Please note that I am able to do late binding using jobParameters. But using stepExecutionContext, I get following exc. I tried lot of posts in forums but am unable to resolve it:

Throwable occurred: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'lazyBindingProxy.itemReader_S4_JPolicy#sysinit' defined in class path resource [Load_InforceToStage.xml]: Initialization of bean failed; nested exception is java.lang.IllegalStateException: Cannot bind to placeholder: stepExecutionContext['readQuery']
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:480)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
at java.security.AccessController.doPrivileged(AccessController.java:224)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
at org.springframework.beans.factory.support.AbstractBeanFactory$2.getObject(AbstractBeanFactory.java:302)
at org.springframework.batch.core.scope.StepScope.get(StepScope.java:150)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164)
at org.springframework.batch.core.scope.util.PlaceholderTargetSource.getTarget(PlaceholderTargetSource.java:185)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:184)
at $Proxy1.close(Unknown Source)
at org.springframework.batch.item.support.CompositeItemStream.close(CompositeItemStream.java:83)
at org.springframework.batch.core.step.item.ChunkMonitor.close(ChunkMonitor.java:99)
at org.springframework.batch.item.support.CompositeItemStream.close(CompositeItemStream.java:83)
at org.springframework.batch.core.step.tasklet.TaskletStep.close(TaskletStep.java:297)
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:255)
at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:135)
at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:61)
at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:60)
at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:144)
at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:124)
at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:135)
at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:281)
at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:120)
at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:49)
at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:114)
at org.springframework.batch.core.launch.support.CommandLineJobRunner.start(CommandLineJobRunner.java:349)
at org.springframework.batch.core.launch.support.CommandLineJobRunner.main(CommandLineJobRunner.java:574)
at com.ebsadm.lh.LHSHEDToStage.runJob(LHSHEDToStage.java:124)
at com.ebsadm.lh.LHSHEDToStage.main(LHSHEDToStage.java:111)
at com.ebdadm.lh.TestLHSHEDToStage.testInforceLoadToStage(TestLHSHEDToStage.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:48)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:600)
at junit.framework.TestCase.runTest(TestCase.java:168)
at junit.framework.TestCase.runBare(TestCase.java:134)
at junit.framework.TestResult$1.protect(TestResult.java:110)
at junit.framework.TestResult.runProtected(TestResult.java:128)
at junit.framework.TestResult.run(TestResult.java:113)
at junit.framework.TestCase.run(TestCase.java:124)
at junit.framework.TestSuite.runTest(TestSuite.java:232)
at junit.framework.TestSuite.run(TestSuite.java:227)
at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:79)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

Caused by: java.lang.IllegalStateException: Cannot bind to placeholder: stepExecutionContext['readQuery'] at org.springframework.batch.core.scope.util.PlaceholderTargetSource$1.convertIfNecessary(PlaceholderTargetSource.java:140) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.convertForProperty(AbstractAutowireCapableBeanFactory.java:1294) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1250) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1010) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:472) ... 50 more

Kindly help.


回答1:


I would expect a call to getExecutionContext on the StepExecution to give you the proper context.

@Override
public void beforeStep(StepExecution execution) {
    String s = "select getdate()";
    execution.getExecutionContext().putString("readQuery", s);  
} 

Your current solution is getting the StepContext. The StepContext is the object that is exposed and used for expression parsing, whereas the ExecutionContext associated with the StepExecution is the actual stepExecutionContext. ItemReaders and ItemWriters and such object also use the ExecutionContext to update the state (skipped items, commit count etc.).




回答2:


Try any of the below :

  1. Use promotionListener bean to promote the scope of variable from step to job.
  2. Use bean instead of executionContext.


来源:https://stackoverflow.com/questions/18830994/spring-batch-late-binding-for-stepexecutioncontext-not-working

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!