java.lang.ClassCastException:无法将java.lang.String强制转换为com.common.batch.model.Customer-Spring Batch CompositeItemReader和Writter [英] java.lang.ClassCastException: java.lang.String cannot be cast to com.common.batch.model.Customer - Spring Batch CompositeItemReader and Writter

查看:76
本文介绍了java.lang.ClassCastException:无法将java.lang.String强制转换为com.common.batch.model.Customer-Spring Batch CompositeItemReader和Writter的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发Spring Batch CompositeItemReader and Writter示例.在此程序中,我试图从mysql db表中读取两个表的数据,并写入单个XML文件.尝试执行此操作时,我看到以下错误即将出现:

I am developing Spring Batch CompositeItemReader and Writter example. In this program I am trying to read data two tables from mysql db table and write to single XML file. When trying to do that I see following error is coming:

java.lang.ClassCastException: java.lang.String cannot be cast to com.common.batch.model.Customer
    at com.common.batch.processor.CustomerProcessor.process(CustomerProcessor.java:1)
    at org.springframework.batch.core.step.item.SimpleChunkProcessor.doProcess(SimpleChunkProcessor.java:126)
    at org.springframework.batch.core.step.item.SimpleChunkProcessor.transform(SimpleChunkProcessor.java:293)
    at org.springframework.batch.core.step.item.SimpleChunkProcessor.process(SimpleChunkProcessor.java:192)
    at org.springframework.batch.core.step.item.ChunkOrientedTasklet.execute(ChunkOrientedTasklet.java:75)
    at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:406)
    at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:330)
    at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)
    at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:271)
    at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:77)
    at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:368)
    at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215)
    at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:144)
    at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:257)
    at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:198)
    at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:148)
    at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:64)
    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:162)
    at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:141)
    at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:134)
    at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:304)
    at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:135)
    at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50)
    at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:128)
    at com.common.batch.main.CompositeXMLMain.main(CompositeXMLMain.java:24)

我没有解决此问题的任何线索.请引导我. Employee.java

I don't have any clue in solving this issue. Please guide me. Employee.java

public class Employee implements Serializable{
    private static final long serialVersionUID = 1L;

    private Integer employeeNumber;
    private String lastName;
    private String firstName;
    private String extension;
    private String email;
    private String officeCode;
    private Integer reportsTo;
    private String jobTitle;
    // setters and getters
@Override
    public String toString() {
        return customerNumber + "|" + customerName + "|" + contactLastName + "|" + contactFirstName + "|" + 
                phone+ "|" + addressLine1 + "|" + addressLine2 + "|" + city + "|" + state+ "|" + postalCode + "|" + 
                country+ "|" + salesRepEmployeeNumber + "|" + creditLimit;
    }
    }

Customer.java

Customer.java

public class Customer implements Serializable{
    private static final long serialVersionUID = 1L;

    private Integer customerNumber;
    private String customerName;
    private String contactLastName;
    private String contactFirstName;
    private String phone;
    private String addressLine1;
    private String addressLine2;
    private String city;
    private String state;
    private String postalCode;
    private String country;
    private Integer salesRepEmployeeNumber;
    private Double creditLimit;
    // setters and getters
@Override
    public String toString() {
        return employeeNumber + "|"+ lastName + "|" + firstName + "|"+ extension + 
                "|" + email + "|" + officeCode+ "|" + reportsTo + "|" + jobTitle;
}
}

xml-jdbc-composite-item-reader-job.xml

xml-jdbc-composite-item-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="compositeItemReader1" writer="itemWriter1" processor="itemCustomerProcessor" 
                commit-interval="5" />
            </tasklet>
        </step>

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


    <!-- ============= Composite Item Reader ================ -->
    <bean id="compositeItemReader1" 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="itemWriter1" 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>

    <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>

        <!-- ======= 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="itemCustomerProcessor" class="com.common.batch.processor.CustomerProcessor" />
    <bean id="itemEmployeeProcessor" class="com.common.batch.processor.EmployeeProcessor" />

</beans>

CompositeXMLMain.java

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 !!");
    }
}

CustomerProcessor.java

Edit-1: CustomerProcessor.java

public class CustomerProcessor implements ItemProcessor<Customer, Customer>{

    @Override
    public Customer process(Customer result) throws Exception {
        System.out.println("Processing result :"+result);

        return result;
    }
}

EmployeeProcessor.java

EmployeeProcessor.java

public class EmployeeProcessor implements ItemProcessor<Employee, Employee>{

    @Override
    public Employee process(Employee result) throws Exception {
        System.out.println("Processing result :"+result);
        return result;
    }
}

CustomerMapper.java

Edit-2: CustomerMapper.java

public class CustomerMapper implements RowMapper<Customer>{

    @Override
    public Customer mapRow(ResultSet rs, int rowNum) throws SQLException {
        Customer customer = new Customer();
        customer.setCustomerNumber(rs.getInt("customerNumber"));
        customer.setCustomerName(rs.getString("customerName"));
        customer.setContactLastName(rs.getString("contactLastName"));
        customer.setContactFirstName(rs.getString("contactFirstName"));
        customer.setPhone(rs.getString("phone"));
        customer.setAddressLine1(rs.getString("addressLine1"));
        customer.setAddressLine2(rs.getString("addressLine2"));
        customer.setCity(rs.getString("city"));
        customer.setState(rs.getString("state"));
        customer.setPostalCode(rs.getString("postalCode"));
        customer.setCountry(rs.getString("country"));
        customer.setSalesRepEmployeeNumber(rs.getInt("salesRepEmployeeNumber"));
        customer.setCreditLimit(rs.getDouble("creditLimit"));

        return customer;
    }
}

EmployeeMapper.java

EmployeeMapper.java

public class EmployeeMapper implements RowMapper<Employee>{

    @Override
    public Employee mapRow(ResultSet rs, int rowNum) throws SQLException {
        Employee employee = new Employee();
        employee.setEmployeeNumber(rs.getInt("employeeNumber"));
        employee.setLastName(rs.getString("lastName"));
        employee.setFirstName(rs.getString("firstName"));
        employee.setExtension(rs.getString("extension"));
        employee.setEmail(rs.getString("email"));
        employee.setOfficeCode(rs.getString("officeCode"));
        employee.setReportsTo(rs.getInt("reportsTo"));
        employee.setJobTitle(rs.getString("jobTitle"));

        return employee;
    }
}

我看到以下几个问题:

  • 我看到下面显示了非常奇怪的XML输出
  • 我只得到第二个数据库表数据,而第一个表数据被覆盖

XML输出?

<?xml version="1.0" encoding="UTF-8"?>
<employees>
   <string>1002|Murphy|Diane|x5800|dmurphy@classicmodelcars.com|1|0|President</string>
   <string>1056|Patterson|Mary|x4611|mpatterso@classicmodelcars.com|1|1002|VP Sales</string>
   <string>1076|Firrelli|Jeff|x9273|jfirrelli@classicmodelcars.com|1|1002|VP Marketing</string>
   <string>1088|Patterson|William|x4871|wpatterson@classicmodelcars.com|6|1056|Sales Manager (APAC)</string>
   <string>1102|Bondur|Gerard|x5408|gbondur@classicmodelcars.com|4|1056|Sale Manager (EMEA)</string>
   <string>1143|Bow|Anthony|x5428|abow@classicmodelcars.com|1|1056|Sales Manager (NA)</string>
   <string>1165|Jennings|Leslie|x3291|ljennings@classicmodelcars.com|1|1143|Sales Rep</string>
   <string>1166|Thompson|Leslie|x4065|lthompson@classicmodelcars.com|1|1143|Sales Rep</string>
   <string>1188|Firrelli|Julie|x2173|jfirrelli@classicmodelcars.com|2|1143|Sales Rep</string>
   <string>1216|Patterson|Steve|x4334|spatterson@classicmodelcars.com|2|1143|Sales Rep</string>
   <string>1286|Tseng|Foon Yue|x2248|ftseng@classicmodelcars.com|3|1143|Sales Rep</string>
   <string>1323|Vanauf|George|x4102|gvanauf@classicmodelcars.com|3|1143|Sales Rep</string>
   <string>1337|Bondur|Loui|x6493|lbondur@classicmodelcars.com|4|1102|Sales Rep</string>
   <string>1370|Hernandez|Gerard|x2028|ghernande@classicmodelcars.com|4|1102|Sales Rep</string>
   <string>1401|Castillo|Pamela|x2759|pcastillo@classicmodelcars.com|4|1102|Sales Rep</string>
   <string>1501|Bott|Larry|x2311|lbott@classicmodelcars.com|7|1102|Sales Rep</string>
   <string>1504|Jones|Barry|x102|bjones@classicmodelcars.com|7|1102|Sales Rep</string>
   <string>1611|Fixter|Andy|x101|afixter@classicmodelcars.com|6|1088|Sales Rep</string>
   <string>1612|Marsh|Peter|x102|pmarsh@classicmodelcars.com|6|1088|Sales Rep</string>
   <string>1619|King|Tom|x103|tking@classicmodelcars.com|6|1088|Sales Rep</string>
   <string>1621|Nishi|Mami|x101|mnishi@classicmodelcars.com|5|1056|Sales Rep</string>
   <string>1625|Kato|Yoshimi|x102|ykato@classicmodelcars.com|5|1621|Sales Rep</string>
   <string>1702|Gerard|Martin|x2312|mgerard@classicmodelcars.com|4|1102|Sales Rep</string>
</employees>

我已更正

<?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="compositeItemReader1" writer="itemWriter1" 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="compositeItemReader1" 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="itemWriter1" 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>

    <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>

        <!-- ======= 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="itemCustomerProcessor" class="com.common.batch.processor.CustomerProcessor" />
    <bean id="itemEmployeeProcessor" class="com.common.batch.processor.EmployeeProcessor" />

</beans>

推荐答案

我不明白,如果无论如何每个都只使用一个阅读器,为什么要使用CompositeItemReaders

i do not understand, why you use CompositeItemReaders if you only use one reader for each, anyways

我猜你是从源代码有:

public class DefaultUnifyingStringItemsMapper implements UnifyingItemsMapper<String> {

    /** {@inheritDoc} */
    @Override
    public String mapItems(List<?> items) throws Exception {
        if (items != null && items.size() > 0) {
            StringBuilder sb = new StringBuilder();
            for (Object item : items) {
                if (item != null) {
                    sb.append(item);
                }
            }
            if (sb.length() > 0) {
                return sb.toString();
            } else {
                return null;
            }
        } else {
            return null;
        }
    }
}

这就是问题所在,它只会创建一个大字符串,该字符串实际上是不是您想要的那种类型(在处理器和编写器中进行处理),现在它不能与需要该项目的处理器一起使用员工类型

so that is the problem, it will just create a big string which is or is not the kind of item you actually want (to process in processor and writer), right now it won't work with the processor which expects items of type Employee

如果您将更多阅读器添加到Compositeitemreader中,则需要重新考虑您的程序,尤其是编写器,他们将使用哪种项目?

if you add more readers to the compositeitemreaders, you need to rethink your program especially the writers, what kind of item will they use?

这篇关于java.lang.ClassCastException:无法将java.lang.String强制转换为com.common.batch.model.Customer-Spring Batch CompositeItemReader和Writter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆