Marshaller must support the class of the marshalled object error in split job with spring batch

微笑、不失礼 提交于 2019-12-11 17:54:37

问题


In a spring batch application that I use to learn , the application is to read from database tables and save in xml files.I tried to split steps so that 2 steps run in parallel (flow) .( I will put only the relevant code if you need more details I will add them ). when I run the job it s read the first 10 record for each step1 and step2 but I get an error after each 10 record readings : java.lang.IllegalStateException: Marshaller must support the class of the marshalled object

jobPerson.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:context="http://www.springframework.org/schema/context"
    xmlns:jdbc="http://www.springframework.org/schema/jdbc">

.
.


    <bean id="processWriter" class="org.springframework.batch.item.xml.StaxEventItemWriter">
           <property name="resource" value="file:xml/process.xml"/>
           <property name="marshaller"  ref="processMarshaller"/>
           <property name="rootTagName" value="process"/>
        </bean>



        <bean id="processPersonWriter" class="org.springframework.batch.item.xml.StaxEventItemWriter">
           <property name="resource" value="file:xml/processPerson.xml"/>
           <property name="marshaller"  ref="processPersonMarshaller"/>
           <property name="rootTagName" value="processPerson"/>
        </bean>

        <bean id="personMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
           <property name="classesToBeBound">
              <value>sb.dbToxml.Person </value>
           </property>
        </bean>
        <bean id="processMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
          <property name="classesToBeBound">
            <value>sb.dbToxml.Process</value>
          </property>
        </bean>
        <bean id="processPersonMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller" >
           <property name="classesToBeBound">
             <value>sb.marshaller.ProcessPerson</value>
           </property>
        </bean>
    <bean id="processReader" class="org.springframework.batch.item.database.JdbcCursorItemReader">
            <property name="dataSource" ref="dataSource"/>
            <property name="sql" value="SELECT CRA_PROCESS_ID,FEED_PROCESS_TYPE_CD from CRA_PROCESS  "></property>
            <property name="rowMapper">
              <bean class="sb.mappers.ProcessMapper">

              </bean>
            </property>
        </bean>

        <bean id="processPersonReader" class="org.springframework.batch.item.database.JdbcCursorItemReader">
          <property name="dataSource" ref="dataSource"></property>
          <property name="sql" value="SELECT cra_process_person_id, sin FROM Cra_Process_Person WHERE cra_process_id &lt; 400"></property>
          <property name="rowMapper">
            <bean  class="sb.mappers.ProcessPersonMapper"></bean>
          </property>
        </bean>


        <!--  ce qui suit pour un job avec  chunk -->
         <batch:job id="personJob">
        <batch:split id="split1" next="step11">
            <batch:flow>
                <batch:step id="step1A1">
                    <batch:tasklet
                        transaction-manager="transactionManager">
                        <batch:chunk reader="processReader"
                            writer="processWriter" commit-interval="10"></batch:chunk>
                    </batch:tasklet>
                </batch:step>
            </batch:flow>
            <batch:flow>
                <batch:step id="step1B1">
                    <batch:tasklet
                        transaction-manager="transactionManager">
                        <batch:chunk reader="processPersonReader"
                            writer="processPersonWriter" commit-interval="10"></batch:chunk>
                    </batch:tasklet>
                </batch:step>
            </batch:flow>
        </batch:split>

        <batch:step id="step11">
            <batch:tasklet transaction-manager="transactionManager">
                <batch:chunk reader="itemReader" writer="itemWriter"
                    commit-interval="30">
                    <batch:listeners>
                        <batch:listener ref="chunkPersonListener" />
                    </batch:listeners>
                </batch:chunk>
            </batch:tasklet>
            <batch:listeners>
                <batch:listener ref="personReadListener" />
            </batch:listeners>
        </batch:step>
        <batch:listeners>
            <batch:listener ref="jobPersonListener" />
        </batch:listeners>
    </batch:job>

</beans>

processMapper :

package sb.mappers;

import java.sql.ResultSet;
import java.sql.SQLException;

import org.springframework.jdbc.core.RowMapper;

import ca.gc.cfp.model.entity.process.CraProcess;

public class ProcessMapper implements RowMapper<CraProcess>
{

  @Override
  public CraProcess mapRow(ResultSet rs, int arg1) throws SQLException
  {
    CraProcess craProcess =new CraProcess();
    craProcess.setCraProcessId(rs.getLong("Cra_Process_Id"));
    craProcess.setFeedProcessTypeCd(rs.getShort("feed_Process_Type_Cd"));
    System.out.println("process Mapper id : "+craProcess.getCraProcessId()+" feed type cd  :"+craProcess.getFeedProcessTypeCd());
    return craProcess;
  }

}

ProcessPersonMapper:

package sb.mappers;

import java.sql.ResultSet;
import java.sql.SQLException;

import org.springframework.jdbc.core.RowMapper;

import ca.gc.cfp.model.entity.process.CraProcessPerson;

public class ProcessPersonMapper implements RowMapper<CraProcessPerson>
{

  @Override
  public CraProcessPerson mapRow(ResultSet rs, int arg1) throws SQLException
  {
    CraProcessPerson craProcessPerson=new CraProcessPerson();
    craProcessPerson.setCraProcessPersonId(rs.getLong("cra_process_person_id"));
    craProcessPerson.setSin(rs.getString("sin"));
    System.out.println("process Person  Mapper id : "+craProcessPerson.getCraProcessPersonId()+" Sin   :"+craProcessPerson.getSin());

    return craProcessPerson;
  }

}

Process.java :

package sb.dbToxml;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="process")
public class Process
{

  long cra_process_id;
  int feed_process_id;

  @XmlElement(name="processId")
  public long getCra_process_id()
  {
    return cra_process_id;
  }
  public void setCra_process_id(long cra_process_id)
  {
    this.cra_process_id = cra_process_id;
  }
  @XmlElement(name="feedProcess")
  public int getFeed_process_id()
  {
    return feed_process_id;
  }
  public void setFeed_process_id(int feed_process_id)
  {
    this.feed_process_id = feed_process_id;
  }

}

ProcessPerson.java :

package sb.marshaller;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="processPerson")
public class ProcessPerson
{
  long cra_process_id ;
  String Sin;
  @XmlElement(name="craProcessId")
  public long getCra_process_id()
  {
    return cra_process_id;
  }
  public void setCra_process_id(long cra_process_id)
  {
    this.cra_process_id = cra_process_id;
  }
  @XmlElement(name="sin")
  public String getSin()
  {
    return Sin;
  }
  public void setSin(String sin)
  {
    Sin = sin;
  }


}

回答1:


processReader is configured with the row mapper sb.mappers.ProcessMapper. This mapper returns items of type CraProcess. However, the processWriter is configured with processMarshaller that is expecting items of type sb.dbToxml.Process. Hence, there is a type mismatch between the reader and the wirter. So either:

  • your ProcessMapper should return Process (and not CraProcess)
  • or your processMarshaller should expect items of type CraProcess (and not Process)

You have the same issue with processPersonReader and processPersonWriter.



来源:https://stackoverflow.com/questions/52005469/marshaller-must-support-the-class-of-the-marshalled-object-error-in-split-job-wi

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