BeanIO - segment manipulation

Andrea Rastelli picture Andrea Rastelli · Nov 19, 2012 · Viewed 7.2k times · Source

This is my problem: I must use BeanIO to read a CSV. This CSV is something like:

s1_el1;s1_el2;s1_el3;s1_el4;X1;Y1;Z1
s2_el1;s2_el2;s2_el3;s2_el4;X2;Y2;Z2
s2_el1;s2_el2;s2_el3;s2_el4;X3;Y3;Z3

Where the sN_elM (where N and M are incremental values for row and column) must be placed in a section (BeanIO section).

What I actually have is a mapping XML like this:

<?xml version="1.0" encoding="UTF-8"?>
<beanio xmlns="http://www.beanio.org/2012/03" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.beanio.org/2012/03 http://www.beanio.org/2012/03/mapping.xsd">   
    <stream name="fileTabellaSconti" format="csv">      
        <parser>
            <property name="delimiter" value=";" />
            <property name="unquotedQuotesAllowed" value="true" />
            <property name="whitespaceAllowed" value="true" />
        </parser>       
        <record name="tabellaSconti" class="map">           
            <segment name="sconto" class="map" >
                <field name="categoria" />
                <field name="nome" />
                <field name="tipologia" />
                <field name="profilo" />
            </segment>          
            <field name="valoreSconto" type="java.lang.Integer" />
            <field name="codiceSts" />
            <field name="scontoEquivalente" type="java.lang.Integer" />         
        </record>       
    </stream>   
</beanio>

In my "writer()" function I do this:

public static void writer( File csv_file )
{
    factory.load(new File(user_dir+"/docroot/WEB-INF/src/it/saleshub/csv/mapping/map_sconto.xml"));

    BeanWriter out = factory.createWriter( "fileTabellaSconti", csv_file );

    int c = 0;
    while (c < 5)
    {
        c++;

        HashMap<String, Object> record = new HashMap<String, Object>();

        HashMap<String, Object> sconto = new HashMap<String, Object>();

        sconto.put( "categoria",        "cat_"+c );
        sconto.put( "nome",             "nome_"+c );
        sconto.put( "tipologia",        "tipologia_"+c );
        sconto.put( "profilo",          "profilo_"+c );

        record.put( "sconto" , sconto );

        record.put( "valoreSconto",     new Integer(c) );
        record.put( "codiceSts",        "sts_"+c );
        record.put( "scontoEquivalente",new Integer(c) );

        System.out.println(record);
        out.write(record);

    }

    out.flush();
    out.close();
}

But every time I use this function, the code show me this exception:

Bean identification failed: no record or group mapping for bean class 'class java.util.HashMap' [...]

Where is my error? I think I'm using in a wrong way the segment, but I can't find any kind of documentation about how to use it correctly..

Answer

Srinivas picture Srinivas · Mar 2, 2013

The issue is in your mapping file and with your pojo classes.

For every field defined in mapping file should have a setter and getter methods in the class defined in the parent tag either segment or record.

Here you used a class map which I think is not available as a pojo in your code. Also if you want to use a collection on a segment you need to use collection attribute and provide value as map or list.

    <record name="tabellaSconti" class="com.test.Parent">           
        <segment name="scontos" collection="list" class="com.test.Sconto" >
            <field name="categoria" />
            <field name="nome" />
            <field name="tipologia" />
            <field name="profilo" />
        </segment>
        <field name="valoreSconto" type="java.lang.Integer" />
        <field name="codiceSts" />
        <field name="scontoEquivalente" type="java.lang.Integer" />         
    </record> 

And in com.test.Parent you have to define getScontos & setScontos methods along with other getter and setter methods for fields out side segment, Also in Sconto class you have to define getters and setters for all the fields defined in segment.

finally code in your main class would be

    Parent record = new Parent;
    Sconto sconto = new Sconto();
    List<Sconto> scontos = new ArrayList<Sconto>();

    sconto.setCategoria("cat_"+c );
    sconto.setNome("nome_"+c );
    sconto.setTipologia("tipologia_"+c );
    sconto.setProfilo("profilo_"+c );

    scontos.add(sconto);

    record.setScontos(scontos);

    -------
    ---------
    out.write(record);