Container for POJO which contains other POJO or list of other POJOs

Hi,
I found it’s not clear for me how to use Container (BeanItemContainer) to control a POJO which contains other POJO or list of other POJOs.
Is there any suggestion, I can learn the Vaadin way of handle data models with complex relationships (one-to-one, one-to-many).

Thank you

I have a similar problem and a, for now, inadequate solution.

The most basic example is a Person object with a nested Address object. Now I’d like to show a lost of Persons and their Addresses inside a table. Is there an easy way to create a Container for this?

I’ve tried several things, but none seem to be very good.

  • I tried creating my own Container and Item implementation, but if you want sorting etc this takes a long time
  • My current solution: I created a “flattened” bean which has all the properties I want to show in the table and has some kind of “copy-constructor” with a Person as parameter. This results in a lot of redundant code, but it’s not too hard

So my question is, is there an easier or “cleaner” solution?

One possible solution I thought about but could not get working, is this: would it be possible to nest columns inside a column? In that case, for instance, the ColumnGenerator or FieldFactory of my Address object could return multiple columns.

You cannot add your own properties to a BeanItemContainer, so if you POJO contains a reference to another POJO, then the referenced POJO will be shown in the table as whatever its toString() method returns. If you want to have more customized output, then you should use IndexedContainer. The downside with IndexedContainer is that you’ll have to populate it manually.

public IndexedContainer createContainer(List<Person> persons) {
    IndexedContainer container = new IndexedContainer();
    container.addContainerProperty("name", String.class, null);
    container.addContainerProperty("address", String.class, null);

    if(persons != null) {
        for(Person person : persons) {
            Item item = container.addItem(person);
            item.getItemProperty("name").setValue(person.getName());
            item.getItemProperty("address").setValue(person.getAddress().getStreet() 
                + ", " + person.getAddress().getZipCode() + " " 
                + person.getAddress().getCity();
        }
    }

    return container;
}

From the Vaadin Book I found:
Scalability of the Table is largely dictated by the container. The default IndexedContainer is relatively heavy and can cause scalability problems, for example, when updating the values. Use of an optimized application-specific container is recommended.

Is there any example how could we implement an optimized application-specific container for
Person {
long id;
String name;
Address address;
List friends;
List books;
}

Address {
long id;
String location;
String country;
}

Book {
long id;
String name;
Person writer;
Publisher publisher;
}

Publisher {
long id;
String name;
}

Sorry to say, but I don’t think IndexedContainer can solve all the problem, if we need to present that Person object, and modify address information, seems like it won’t affect the Address POJO, because we manually created the Address as a property of Person.

In my case, Kim’s solution would work great because I don’t want to edit the table. But if you want to edit the items in your table, you’ll need a little more. Like a custom field that will allow you to edit the bean.