Write Bean containing a list

Help
enR!Gi
2012-12-05
2012-12-10
  • enR!Gi
    enR!Gi
    2012-12-05

    Hi there,

    I never found this in the forum or the documentation.
    So my question is, how can I write a bean which contains a list, and for each element in the list a new csv line is being written.
    I recognized that with ICsvDozerBeanWriter it is possible to access specific indexes within the list, but what I want is that every element in the list is being written.

    public class Bean {
        private List<Recipient> recipients
    }
    

    So a mapping for a specific index would be

    private static final String[] FIELD_MAPPING = new String[] { "recipients[0].mail"};
    

    and my thought was, it might be possible to define something like

    private static final String[] FIELD_MAPPING = new String[] { "recipients[].mail"};
    

    which would then, instead of using only one index, write the whole list.

    Is this possible, or is there another way to solve this?

    Thanks and regards,
    René

     
  • James Bassett
    James Bassett
    2012-12-05

    Hi René,

    Typically,
    1 bean instance == 1 call to write() == 1 row of CSV

    It looks like you're trying to write each recipient's mail field on a new line, so why not iterate through each Recipient and write them instead (of Bean).

    Then your field mapping would simply be "mail". Think of the field mapping as a way of mapping from one bean to one row of CSV.

    Does that help?

     
  • enR!Gi
    enR!Gi
    2012-12-06

    Hi,

    ok - thank you.
    The proposal you suggested also came to my mind but I never accomplished an implementation.

    But according to your answer, I guess my approach was wrong anyway. This is what I've tried so far:

    for (Bean bean : beans) {
        for (Recipient recipient : bean.getRecipients()) {
            beanWriter.write(bean, processors); // <-- And this will not work, of course
        }
    }
    

    So the problem is obvious - I would have to pass over an instance of Recipient, but then the mapping I used to initialize my BeanWriter would fail. And that's where I am stuck right now.
    And if I understood you correctly, this cannot work anyway, as the write-operation is always attached to a single bean.

    What I want to have is a CSV File that looks like this (Assuming I have an additional attribute called 'date' within 'Bean'):

    Recipient Date
    mail1@example.com 2012-12-06
    mail2@example.com 2012-12-06
    Thanx in advance and best regards, René
     
  • James Bassett
    James Bassett
    2012-12-06

    Ok I see now! In order for that to work, you'll need a reference to the Bean in Recipient, e.g.

    public class Recipient {
        private String mail;
        private Bean bean;
        // getters/setters here
    }
    

    Then you can have the following as your field mapping:

    private static final String[] FIELD_MAPPING = 
        new String[] { "mail", "bean.date"};
    
     
  • James Bassett
    James Bassett
    2012-12-07

    Of course, for a simple scenario such as yours it's probably a lot easier to keep things simple and use a CsvListWriter instead of a CsvDozerBeanWriter. Yes it's not as cool, but it gets the job done :)

    for (Bean bean : beans) {
        for (Recipient recipient : bean.getRecipients()) {
            Object[] row = {recipient.getMail(), bean.getDate()};
            listWriter.write(Arrays.asList(row), processors);
        }
    }
    

    Obviously there are limits to using CsvDozerBeanWriter - but for complex nested object graphs it is a lot easier to use.

     
  • enR!Gi
    enR!Gi
    2012-12-10

    Ok, thank you - will play a littlebit wth it and see what I'll use.