Here are the configurations of a spring-batch project.
build.gradle:
apply plugin: 'java'
repositories {
jcenter()
mavenCentral()
maven { url "http://repo.spring.io/libs-milestone" }
}
dependencies {
// https://mvnrepository.com/artifact/org.springframework/spring-core
compile group: 'org.springframework', name: 'spring-core', version: '5.1.3.RELEASE'
// https://mvnrepository.com/artifact/org.springframework/spring-context
compile group: 'org.springframework', name: 'spring-context', version: '5.1.3.RELEASE'
// https://mvnrepository.com/artifact/org.springframework/spring-web
compile group: 'org.springframework', name: 'spring-web', version: '5.1.3.RELEASE'
compile group: 'org.springframework', name: 'spring-webmvc', version: '5.1.3.RELEASE'
// https://mvnrepository.com/artifact/org.springframework.batch/spring-batch-core
compile group: 'org.springframework.batch', name: 'spring-batch-core', version: '4.1.0.RELEASE'
// https://mvnrepository.com/artifact/org.springframework.batch/spring-batch-infrastructure
compile group: 'org.springframework.batch', name: 'spring-batch-infrastructure', version: '4.1.0.RELEASE'
// https://mvnrepository.com/artifact/org.springframework.batch/spring-batch-test
testCompile group: 'org.springframework.batch', name: 'spring-batch-test', version: '4.1.0.RELEASE'
// https://mvnrepository.com/artifact/org.springframework.data/spring-data-mongodb
compile group: 'org.springframework.data', name: 'spring-data-mongodb', version: '2.1.3.RELEASE'
compile group: 'org.mongodb', name: 'mongo-java-driver', version: '3.9.1'
compile group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.6'
// https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core
compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.9.7'
}
Job configuration:
<batch:job id="batchUpdateJob" job-repository="jobRepository">
<batch:step id="step1" next="step2">
<batch:tasklet allow-start-if-complete="true">
<batch:chunk reader=“reader1”
writer="compositeWriter" processor=“processor1” commit-interval="10" />
</batch:tasklet>
</batch:step>
<batch:step id="step2">
<batch:tasklet allow-start-if-complete="true">
<batch:chunk reader=“reader2”
writer=“writer2” processor=“processor2” commit-interval="10" />
</batch:tasklet>
</batch:step>
</batch:job>
main() where the batch job is run:
public static void main(String[] args) {
// Loading The Bean Definition From The Spring Configuration File
contextObj = new ClassPathXmlApplicationContext(springConfig);
jobObj = (Job) contextObj.getBean(JOB_NAME);
jobLauncherObj = (JobLauncher) contextObj.getBean(JOB_LAUNCHER_NAME);
try {
JobParametersBuilder jobBuilder = new JobParametersBuilder();
JobExecution execution = jobLauncherObj.run(jobObj, jobParameters);
System.out.println("Exit Status : " + execution.getStatus());
} catch (Exception exceptionObj) {
exceptionObj.printStackTrace();
}
System.out.println("Done");
}
For each run of the main(), the exitStatus
of the job executed is either COMPLETED
or FAILED
, though no change to the project is made in between the runs.
And when the exit status is FAILED
, the stepExecutions
has the following trace:
[StepExecution: id=1, version=2, name=step1, status=FAILED, exitStatus=FAILED, readCount=0, filterCount=0, writeCount=0 readSkipCount=0, writeSkipCount=0, processSkipCount=0, commitCount=0, rollbackCount=0, exitDescription=org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.reader1' defined in class path resource [spring/batch/jobs/spring-beans.xml]: Initialization of bean failed; nested exception is org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'java.lang.String' to required type 'org.springframework.data.mongodb.core.query.Query' for property 'query'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'org.springframework.data.mongodb.core.query.Query' for property 'query': no matching editors or conversion strategy found at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:584) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:498) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$1(AbstractBeanFactory.java:356) at org.springframework.batch.core.scope.StepScope.get(StepScope.java:113) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:353) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) at org.springframework.aop.target.SimpleBeanTargetSource.getTarget(SimpleBeanTargetSource .java:35) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:193) at com.sun.proxy.$Proxy18.open(Unknown Source) at org.springframework.batch.item.support.CompositeItemStream.open(CompositeItemStream.java:103) at org.springframework.batch.core.step.tasklet.TaskletStep.open(TaskletStep.java:311) at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:200) at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:148) at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:68) at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:67) at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:169) at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:144) at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:136) at org.springframework.batch.core.job.Abstr actJob.execute(AbstractJob.java:313) at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:144) at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50) at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:137) at com.simba.tool.cacheserver.batchprocess.App.main(App.java:39) Caused by: org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'java.lang.String' to required type 'org.springframework.data.mongodb.core.query.Query' for property 'query'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'org.springframework.data.mongodb.core.query.Query' for property 'query': no matching editors or conversion strategy found at org.springframework.beans.AbstractNestablePropertyAccessor.convertIfNecessary(AbstractNestablePropertyAccessor.java:590) at org.springframework.beans.AbstractNestablePropertyAccessor.convertForProperty(AbstractNestablePropertyAccessor.java:604) at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:219) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.convertForProperty(AbstractAutowireCapableBeanFactory.java:1697) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1653) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.ja va:1400) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:575) ... 22 more Caused by: java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'org.springframework.data.mongodb.core.query.Query' for property 'query': no matching editors or conversion strategy found at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:299) at org.springframework.beans.AbstractNestablePropertyAccessor.convertIfNecessary(AbstractNestablePropertyAccessor.java:585) ... 28 more ]
Bean defining both the readers are configured like this:
<bean id="reader"
class="org.springframework.batch.item.data.MongoItemReader" scope="step">
<property name="template" ref="mongoTemplate" />
<property name="collection" value="Collection" />
<property name="targetType" value="com.example.SomeObject" />
<property name="query" value="{ $and : [ { 'Field1': /.*#{jobParameters['Param1']}.*/ }, { 'Field2': { $gte: ISODate('9999-12-30T00:00:00Z') } }, { 'Field3': { '$eq': 'Open' } } ] }" />
<property name="sort">
<util:map>
<entry key="Field4" value="#{T(org.springframework.data.domain.Sort.Direction).ASC}" />
</util:map>
</property>
<property name="fields" value="{ 'Field5': 1, 'Field6': 1, 'Field7': 1 }" />
</bean>
Previous research:
My search on the exception message: Cannot convert value of type 'java.lang.String' to required type 'org.springframework.data.mongodb.core.query.Query' for property 'query'
did not fetch any relevant results. The research using keywords like the ones in the title of this question did not shed much light either.
Why does the execution of the batch job fail sometimes and finish other times? What is the fix for this?
Update: Tried changing the definition of the readers to this:
<bean id="query" class="java.lang.String">
<constructor-arg value="your json query here"/>
</bean>
<bean id="mongoItemReader" class="org.springframework.batch.item.data.MongoItemReader">
<property name="query" ref="query"/>
<!-- define other properties of the reader here -->
</bean>
Now ended up with the following trace:
[StepExecution: id=1, version=2, name=step1, status=FAILED, exitStatus=FAILED, readCount=0, filterCount=0, writeCount=0 readSkipCount=0, writeSkipCount=0, processSkipCount=0, commitCount=0, rollbackCount=0, exitDescription=org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.reader' defined in class path resource [spring/batch/jobs/spring-beans.xml]: Initialization of bean failed; nested exception is org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'com.sun.proxy.$Proxy19 implementing java.io.Serializable,java.lang.Comparable,java.lang.CharSequence,org.springframework.aop.scope.ScopedObject,org.springframework.aop.framework.AopInfrastructureBean,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised,org.springframework.core.DecoratingProxy' to required type 'org.springframework.data.mongodb.core.query.Query' for property 'query'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'com.sun.proxy.$Proxy19 implementing java.io.Serializable,java.lang.Comparable,java.lang.CharSequence,org.springframework.aop.scope.ScopedObject,org.springframework.aop.framework.AopInfrastructureBean,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised,org.springframework.core.DecoratingProxy' to required type 'org.springframework.data.mongodb.core.query.Query' for property 'query': no matching editors or conversion strategy found at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:584) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:498) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$1(AbstractBeanFactory.java:356) at org.springframework.batch.core.scope.StepScope.get(StepScope.java: 113) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:353) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) at org.springframework.aop.target.SimpleBeanTargetSource.getTarget(SimpleBeanTargetSource.java:35) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:193) at com.sun.proxy.$Proxy18.open(Unknown Source) at org.springframework.batch.item.support.CompositeItemStream.open(CompositeItemStream.java:103) at org.springframework.batch.core.step.tasklet.TaskletStep.open(TaskletStep.java:311) at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:200) at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:148) at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:68) at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:67) at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:169) at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:144) at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:136) at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:313) at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:144) at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50) at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:137) at com.simba.tool.cacheserver.batchprocess.App.main(App.java:41) Caused by: org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'com.sun.proxy.$Proxy19 implementing java.io.Serializable,java.lang.Comparable,java.lang.CharSequence,org.springframework.aop.scope.ScopedObject,org.springframework.aop.framework.AopInfrastructureBean, org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised,org.springframework.core.DecoratingProxy' to required type 'org.springframework.data.mongodb.core.query.Query' for property 'query'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'com.sun.proxy.$Proxy19 implementing java.io.Serializable,java.lang.Comparable,java.lang.CharSequence,org.springframework.aop.scope.ScopedObject,org.springframework.aop.framework.AopInfrastructureBean,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised,org.springframework.core.DecoratingProxy' to required type 'org.springframework.data.mongodb.core.query.Query' for property 'query': no matching editors or conversion strategy found at org.springframework.beans.AbstractNestablePropertyAccessor.convertIfNecessary(AbstractNestablePropertyAccessor.java:590) at org.springframework.beans.AbstractNestablePropertyAccessor.convertForProperty(AbstractNestablePropertyAccessor.java:604) at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:219) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.convertForProperty(AbstractAutowireCapa bleBeanFactory.java:1697) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1653) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1400) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:575) ... 22 more Caused by: java.lang.IllegalStateException: Cannot convert value of type 'com.sun.proxy.$Proxy19 implementing java.io.Serializable,java.lang.Comparable,java.lang.CharSequence,org.springframework.aop.scope.ScopedObject,org.springframework.aop.framework.AopInfrastructureBean,org.springframework.aop.SpringProxy,org.springframework.aop.framework.Advised,org.springframework.core.DecoratingProxy' to required type 'org.springframework.data.mongodb.core.query.Query' for property 'query': no matching editors or conversion strategy found at or g.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:299) at org.springframework.beans.AbstractNestablePropertyAccessor.convertIfNecessary(AbstractNestablePropertyAccessor.java:585) ... 28 more ]
There are two setQuery
methods in MongoItemReader
: setQuery(Query)
and setQuery(String)
. So when configured with XML, there might be an ambiguity on which one to use. In your case, it looks like Spring is trying to convert your String
query into a org.springframework.data.mongodb.core.query.Query
object and it does not find a converter for that.
You need to specify which type of query to use and set it on the reader.
In your example, you need to configure the query and the reader with something like:
<bean id="query" class="java.lang.String">
<constructor-arg value="your json query here"/>
</bean>
<bean id="mongoItemReader" class="org.springframework.batch.item.data.MongoItemReader">
<property name="query" ref="query"/>
<!-- define other properties of the reader here -->
</bean>
Hope this helps.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.