无法将类型 [] 的值转换为 属性 'cursorItemReaders[0]' 所需的类型 []:未找到匹配的编辑器或转换策略

Cannot convert value of type [] to required type [] for property 'cursorItemReaders[0]': no matching editors or conversion strategy found

我正在开发 Spring Batch 示例。在此示例中,我希望开发 compositeJdbcReadercompositeJdbcWritter API 以将数据库表数据转换为单个 XML 文件。尝试这样做时,我遇到以下错误:

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'compositeJdbcReaderStep': Cannot resolve reference to bean 'compositeItemReader' while setting bean property 'itemReader'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'compositeItemReader' defined in class path resource [composite/xml-jdbc-composite-item-reader-job.xml]: Initialization of bean failed; nested exception is org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type [java.util.ArrayList] to required type [java.util.List] for property 'cursorItemReaders'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [org.springframework.batch.core.job.flow.FlowJob] to required type [org.springframework.batch.item.database.AbstractCursorItemReader] for property 'cursorItemReaders[0]': no matching editors or conversion strategy found
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:359)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1481)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1226)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getObject(AbstractBeanFactory.java:306)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:753)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
    at com.common.batch.main.CompositeXMLMain.main(CompositeXMLMain.java:17)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'compositeItemReader' defined in class path resource [composite/xml-jdbc-composite-item-reader-job.xml]: Initialization of bean failed; nested exception is org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type [java.util.ArrayList] to required type [java.util.List] for property 'cursorItemReaders'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [org.springframework.batch.core.job.flow.FlowJob] to required type [org.springframework.batch.item.database.AbstractCursorItemReader] for property 'cursorItemReaders[0]': no matching editors or conversion strategy found
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:553)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getObject(AbstractBeanFactory.java:306)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:351)
    ... 15 more
Caused by: org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type [java.util.ArrayList] to required type [java.util.List] for property 'cursorItemReaders'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [org.springframework.batch.core.job.flow.FlowJob] to required type [org.springframework.batch.item.database.AbstractCursorItemReader] for property 'cursorItemReaders[0]': no matching editors or conversion strategy found
    at org.springframework.beans.AbstractNestablePropertyAccessor.convertIfNecessary(AbstractNestablePropertyAccessor.java:591)
    at org.springframework.beans.AbstractNestablePropertyAccessor.convertForProperty(AbstractNestablePropertyAccessor.java:603)
    at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:204)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.convertForProperty(AbstractAutowireCapableBeanFactory.java:1527)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1486)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1226)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543)
    ... 21 more
Caused by: java.lang.IllegalStateException: Cannot convert value of type [org.springframework.batch.core.job.flow.FlowJob] to required type [org.springframework.batch.item.database.AbstractCursorItemReader] for property 'cursorItemReaders[0]': no matching editors or conversion strategy found
    at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:302)
    at org.springframework.beans.TypeConverterDelegate.convertToTypedCollection(TypeConverterDelegate.java:570)
    at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:216)
    at org.springframework.beans.AbstractNestablePropertyAccessor.convertIfNecessary(AbstractNestablePropertyAccessor.java:576)
    ... 27 more

不确定这里出了什么问题。请指导

xml-jdbc-复合项-reader-job.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:batch="http://www.springframework.org/schema/batch"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:util="http://www.springframework.org/schema/util"
    xsi:schemaLocation="http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd">

    <import resource="classpath:context-datasource.xml" />

    <!-- JobRepository and JobLauncher are configuration/setup classes -->
    <bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean" />

    <bean id="jobLauncher"  class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
        <property name="jobRepository" ref="jobRepository" />
    </bean>


    <!-- Step will need a transaction manager -->
    <bean id="transactionManager"
        class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" />


    <!-- =========================================================== -->    
    <job id="compositeJdbcReaderJob" xmlns="http://www.springframework.org/schema/batch">
        <step id="compositeJdbcReaderStep" next="compositeJdbcReaderStep2">
            <tasklet>
                <chunk reader="compositeItemReader" writer="itemWriter" commit-interval="5" />
            </tasklet>
        </step>

        <step id="compositeJdbcReaderStep2">
            <tasklet>
                <chunk reader="compositeItemReader2" writer="itemWriter2" commit-interval="5" />
            </tasklet>
        </step>
    </job>


    <!-- ============= Composite Item Reader ================ -->
    <bean id="compositeItemReader" class="com.common.batch.reader.CompositeCursorItemReader">
        <property name="unifyingMapper">
            <bean class="com.common.batch.mapper.DefaultUnifyingStringItemsMapper" />
        </property>
        <property name="cursorItemReaders">
            <list>
                <ref bean="itemReader1" />
            </list>
        </property>
    </bean>

    <bean id="compositeItemReader2" class="com.common.batch.reader.CompositeCursorItemReader">
        <property name="unifyingMapper">
            <bean class="com.common.batch.mapper.DefaultUnifyingStringItemsMapper" />
        </property>
        <property name="cursorItemReaders">
            <list>
                <ref bean="itemReader2" />                 
            </list>
        </property>
    </bean>


    <!-- ========== ItemReader =============== -->
    <bean id="itemReader1" class="org.springframework.batch.item.database.JdbcCursorItemReader">
        <property name="dataSource" ref="dataSource" />

        <property name="saveState" value="true" />

        <property name="sql">
            <value>
                <![CDATA[ ${select.sql.customers} ]]>
            </value>
        </property>
        <property name="rowMapper">
            <bean class="com.common.batch.mapper.CustomerMapper" />
        </property>
    </bean>


    <bean id="itemReader2" class="org.springframework.batch.item.database.JdbcCursorItemReader">
        <property name="dataSource" ref="dataSource" />

        <property name="saveState" value="true" />

        <property name="sql">
            <value>
                <![CDATA[ ${select.sql.employees} ]]>
            </value>
        </property>
        <property name="rowMapper">
            <bean class="com.common.batch.mapper.EmployeeMapper" />
        </property>
    </bean>


    <!-- ItemWritter -->
    <bean id="itemWriter" class="org.springframework.batch.item.xml.StaxEventItemWriter">
        <property name="resource" value="file:xml/customers.xml" />

        <property name="marshaller" ref="customerUnmarshaller" />

        <property name="rootTagName" value="customers" />
    </bean>

    <!-- ======= Customer Unmarshaller ======== -->
    <bean id="customerUnmarshaller" class="org.springframework.oxm.xstream.XStreamMarshaller">
        <property name="aliases">
            <util:map id="aliases">
                <entry key="customer" value="com.common.batch.model.Customer" />
            </util:map>
        </property>
    </bean>


    <bean id="itemWriter2" class="org.springframework.batch.item.xml.StaxEventItemWriter">
        <property name="resource" value="file:xml/customers.xml" />

        <property name="marshaller" ref="employeeUnmarshaller" />

        <property name="rootTagName" value="employees" />
    </bean>

    <!-- ======= Employee Unmarshaller ======== -->
    <bean id="employeeUnmarshaller" class="org.springframework.oxm.xstream.XStreamMarshaller">
        <property name="aliases">
            <util:map id="aliases">
                <entry key="employee" value="com.common.batch.model.Employee" />
            </util:map>
        </property>
    </bean>


    <bean id="itemCustomerProcessor" class="com.common.batch.processor.CustomerProcessor" />
    <bean id="itemEmployeeProcessor" class="com.common.batch.processor.EmployeeProcessor" />


    <job id="itemReader1" xmlns="http://www.springframework.org/schema/batch">
        <step id="step1">
            <tasklet transaction-manager="transactionManager">
                <chunk reader="compositeItemReader" writer="itemWriter" processor="itemCustomerProcessor" commit-interval="1" />
            </tasklet>
        </step>
    </job>


    <job id="itemReader2" xmlns="http://www.springframework.org/schema/batch">
        <step id="step2">
            <tasklet transaction-manager="transactionManager">
                <chunk reader="compositeItemReader2" writer="itemWriter2" processor="itemEmployeeProcessor" commit-interval="1" />
            </tasklet>
        </step>
    </job>

</beans>

CompositeXMLMain.java

public class CompositeXMLMain {
    @SuppressWarnings("resource")
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("composite/xml-jdbc-composite-item-reader-job.xml");

        JobLauncher jobLauncher = (JobLauncher) context.getBean("jobLauncher");
        Job job = (Job) context.getBean("compositeJdbcReaderJob");

        JobExecution execution;
        try {
            execution = jobLauncher.run(job, new JobParameters());
            System.out.println("Job Exit Status : "+ execution.getStatus());

        } catch (JobExecutionAlreadyRunningException | JobRestartException
                | JobInstanceAlreadyCompleteException | JobParametersInvalidException e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
        System.out.println("Done !!");
    }
}

我通过删除以下标签解决了这个问题:

  <job id="itemReader1" xmlns="http://www.springframework.org/schema/batch">
        <step id="step1">
            <tasklet transaction-manager="transactionManager">
                <chunk reader="compositeItemReader" writer="itemWriter" processor="itemCustomerProcessor" commit-interval="1" />
            </tasklet>
        </step>
    </job>


    <job id="itemReader2" xmlns="http://www.springframework.org/schema/batch">
        <step id="step2">
            <tasklet transaction-manager="transactionManager">
                <chunk reader="compositeItemReader2" writer="itemWriter2" processor="itemEmployeeProcessor" commit-interval="1" />
            </tasklet>
        </step>
    </job>