0

I have a spring boot with a spring batch application that processes one input XML file, as you can see the XML has a container element results and a repeating element contact. While trying to process it I'm getting the error describe at the end:

<?xml version="1.0" encoding="UTF-8" ?>
<query>
    <id>123</id>
    <tracking>555</tracking>
    <results>
        <contact>
            <full_name>
                <first_name>John</first_name>
                <last_name>Doe</last_name>
            </full_name>
            <street>123 Main St</street>
            <city>Chicago</city>
            <state>IL</state>
            <zip>60610</zip>
        </contact>
        <contact>
            <full_name>
                <first_name>Jane</first_name>
                <last_name>Smith</last_name>
            </full_name>
            <street>123 Main St</street>
            <city>Miami</city>
            <state>FL</state>
        </contact>
    </results>
</query>

beanio-configuration.xml (Using @nicoschl suggestion)

<beanio xmlns="http://www.beanio.org/2012/03">
    <stream name="query" format="xml" strict="true" ignoreUnidentifiedRecords="true">
        <record name="id"></record>
        <record name="tracking"></record>
        <record name="results" class="com.test.springbatchapp.model.ContactList">
            <segment name="contact" collection="list" class="com.test.springbatchapp.model.Contact" occurs="0+">
                <segment name="full_name">
                    <field name="firstName" xmlName="first_name" maxLength="20" />
                    <field name="lastName" xmlName="last_name" maxLength="30" />
                </segment>
                <field name="street" maxLength="30" />
                <field name="city" maxLength="25" />
                <field name="state" minLength="2" maxLength="2" />
                <field name="zip" regex="\d{5}" minOccurs="0" default="" />
            </segment>
        </record>
    </stream>
</beanio>

Contact.java

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Contact {
    
    private String firstName;
    private String lastName;
    private String street;
    private String city;
    private String state;
    private String zip;
}

ContactList.java

@Data
@AllArgsConstructor
@NoArgsConstructor
public class ContactList {
    
    private List<Contact> contact;
}

Reader:

@Bean
public ItemReader<Contact> reader() {
    BeanIOFlatFileItemReader<Contact> reader = new BeanIOFlatFileItemReader<>();
    try {
        reader.setResource(new FileSystemResource(fileInputContact));
        reader.setStreamName(inputContactStreamName);
        reader.setStreamMapping(new ClassPathResource(beanIoConfigurationXmlPath));
        reader.setStreamFactory(StreamFactory.newInstance());
        reader.getLineNumber();
        reader.afterPropertiesSet();
    } catch (Exception e) {
        log.error("ERROR: An issue occurred in the BeanIO Item Reader:: {} {}", e.getMessage(), e.getStackTrace());
    }
    
    return reader;      
}

Writer:

@Bean
public FlatFileItemWriter<Contact> writer() {
    FlatFileItemWriter<Contact> writer = new FlatFileItemWriter<>();
    writer.setResource(new FileSystemResource(fileOutputContact));
    writer.setLineAggregator(new DelimitedLineAggregator<Contact>() {
        {
            setDelimiter(",");
            setFieldExtractor(new BeanWrapperFieldExtractor<Contact>() {
                {
                    setNames(new String[] { "firstName", "lastName", "street", "city", "state", "zip" });
                }                   
            });
        }
    });
    
    return writer;
}

Job and Step:

@Bean
public Job importUserJob(Step step1) {
    return jobBuilderFactory.get("importUserJob")
      .incrementer(new RunIdIncrementer())          
      .flow(step1)
      .end()
      .build();
}

@Bean
public Step step1(FlatFileItemWriter<Contact> writer) {
    return stepBuilderFactory.get("step1")
      .<Contact, Contact> chunk(10)
      .reader(reader())
      .processor(processor())
      .writer(writer)
      .build();
}

I'm having: Encountered an error executing step step1 in job importUserJob, com.test.springbatchapp.model.ContactList cannot be cast to com.test.springbatchapp.model.Contact

What changes do I have to make to solve above error?

Somebody
  • 2,667
  • 14
  • 60
  • 100
  • Please show the structure of your Java objects as well? – nicoschl Dec 07 '22 at 22:40
  • I'm not familiar with how Spring Batch integrates with BeanIO. From the error you are getting, it looks like your writer is receiving an instance of `ContactList` instead of what you expect it to be. Are you interested in processing the full XML file or only the `Contact` records? – nicoschl Dec 13 '22 at 21:21
  • it will be good to be able to process everything, but right now the `Contact` records only – Somebody Dec 14 '22 at 14:53

1 Answers1

0

It is not the results record that is repeatable, so remove the occurs attribute. It is your contact segment that is repeatable.

Try this:

<stream name="query" format="xml" strict="true" ignoreUnidentifiedRecords="true">
    <record name="id"></record>
    <record name="tracking"></record>
    <record name="results" class="com.test.model.InputXml">
        <segment name="contact" collection="list" class="com.test.model.Contact" occurs="0+">
            <segment name="full_name">
                <field name="firstName" xmlName="first_name" maxLength="20" />
                <field name="lastName" xmlName="last_name" maxLength="30" />
            </segment>
            <field name="street" maxLength="30" />
            <field name="city" maxLength="25" />
            <field name="state" minLength="2" maxLength="2" />
            <field name="zip" regex="\d{5}" minOccurs="0" default="" />
        </segment>
    </record>
</stream>
nicoschl
  • 2,346
  • 1
  • 17
  • 17
  • You still need some object to hold your list of `contact` segments for processing afterwards. Unless you process the `contact` segment as it is read, but that will change things. – nicoschl Dec 08 '22 at 14:38
  • I have rephrased my question and added all details including your suggestion. Please review it again and see the error I'm getting – Somebody Dec 09 '22 at 14:04