Binding Vaadin Table to JPA .getResultList()

Hello

The Scotsman again - with another newbie problem

Seriously - I’m sure this is simplistic stuff - but I really am struggling with Binding Vaadin Table to JPA .getResultList()

I can now get a query result from my app using query.getResultList(); - but I understand this returns an Object of type Java.Util.list.

Can I use this as a data binding to a Vaadin Table? - so far I’ve tried :

IndexedContainer ic = new IndexedContainer(query.getResultList());
Table table1 = new Table(“Actors Listing”)
table1.setContainerDataSource(ic);

This produces an empty table - as you might expect!

Tried Type Casting - but just got more confused…

I did understand from a previous posting on
Dynamic SQL and Vaadin Table Component


A fresh IndexedContainer has no properties, and thus nothing is shown in the Table.

This posting went on to use :
qcSQL = new QueryContainer(“SELECT * FROM EMP”,conn);
tblDataTable.setContainerDataSource(qcSQL);

but that does not apply to JPA…

Can anyone give me a few pointers??

As always any help will be appreciated

Regards

Jim

Have you check that the collection returned from getResultList actually contains something? I suggest you put a breakpoint straight after the .getResultList(), and look with the debugger that the list that it return actually contains something. It may be an empty list!

Using new IndexedContainer((list)query.getResultList()); should actually produce some output. You’ll just get one column with the list of the objects - every row having the .toString() of the object as caption. It should not produce an empty table, as long as the list is not empty.

Hello Jens

Thanks for the speedy response

getResultList contains 200 Objects (as it should - it’s the Actor Table of MySQL’s Sakila sample database…)

My newbie problem is - I just don’t know how to bind the list to a Vaadin Table - and I’m running out of things to try

As I keep banging on - an Application without persistent data is pretty useless - though it may be pretty…

Either

Your documentation falls down when it comes to Data Binding - unlikely - as I think it superb everywhere else,

or - more probably

I should already know this stuff…

Either way I am (very much) stuck

Kindest Regards

Jim

Allright, I have to apologize, I pushed you to the wrong direction.

I just talked with one of the main developers of Vaadin, and apparently a container created with new IndexedContainer(Collection) can be used for EVERY other AbstractSelect, except Table. That means that you can use them in a ComboBox, ListSelect, NativeSelect, TwinColSelect, OptionGroup and even a Tree, but not in the Table. Hmpf. This is because, by defaut, a table has many columns, and the other AbstractSelects has only one. Anyhow, there is two options left to use - you populate your own item and properties to a IndexedContainer, or you use a BeanItemContainer that does that for you. More on these in a while.

A little info on how data binding works in Vaadin. You probably know this already but I won’t hurt to write it down. Every AbstractSelect (listed above) uses a container to store all the info that shall show. Every row in a container is represented with an Item -object. The container also defines a list of properties that every item has to specify. If you define the properties “foo”, “bar” and “baz” to the container, the names of the columns in the table using the container will be the same “foo”,“bar”,baz", and every item will also have these three properties.

So - One container has n amount of items (represented as rows), every item has n amount of properties (represented as cells.

In an IndexedContainer you specify all these items and properties yourself. If you opt for a BeanItemContainer it will rely that your objects that will be put to the table are compliant to the JavaBean standard, and do the work of specifying and filling itself. You are also free to create your own container, if you want to.

Here’s an example on how you populate a table with both cases. Hope this helps!

package com.example.playground;

import java.util.ArrayList;
import java.util.List;

import com.vaadin.Application;
import com.vaadin.data.Item;
import com.vaadin.data.util.BeanItemContainer;
import com.vaadin.data.util.IndexedContainer;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Table;
import com.vaadin.ui.Window;

public class PlaygroundApplication extends Application {

    @Override
    public void init() {
        // Main window for the app
        Window mainWindow = new Window("Playground Application");
        mainWindow.setSizeFull();
        HorizontalLayout layout = new HorizontalLayout();
        layout.setSizeFull();
        mainWindow.setContent(layout);

        // A list of persons to be bound to tables.
        List<Person> persons = new ArrayList<Person>();
        persons.add(new Person("Ted", "Mosby"));
        persons.add(new Person("Marshall", "Eriksen"));
        persons.add(new Person("Robin", "Scherbatsky"));
        persons.add(new Person("Barney", "Stinson"));
        persons.add(new Person("Lily", "Aldrin"));

        Table table1 = new Table("Table 1, loop through the items");
        IndexedContainer container1 = new IndexedContainer();
        container1.addContainerProperty("First name", String.class, "");
        container1.addContainerProperty("Last name", String.class, "");
        for (Person person : persons) {
            Item item = container1.addItem(person);
            item.getItemProperty("First name").setValue(person.getFirstName());
            item.getItemProperty("Last name").setValue(person.getLastName());
        }
        table1.setContainerDataSource(container1);

        Table table2 = new Table("Table 2, automation with BeanItemContainer");
        BeanItemContainer<Person> container2 = new BeanItemContainer<Person>(
                persons);
        table2.setContainerDataSource(container2);

        layout.addComponent(table1);
        layout.addComponent(table2);
        setMainWindow(mainWindow);
    }

    public class Person {
        private String firstName;
        private String lastName;

        public Person() {
        }

        public Person(String firstName, String lastName) {
            this.firstName = firstName;
            this.lastName = lastName;
        }

        @Override
        public String toString() {
            return firstName + " " + lastName;
        }

        public String getFirstName() {
            return firstName;
        }

        public void setFirstName(String firstName) {
            this.firstName = firstName;
        }

        public String getLastName() {
            return lastName;
        }

        public void setLastName(String lastName) {
            this.lastName = lastName;
        }
    }
}

And here is a screenshot of the result:

Hello Jens

No need for apologies

I am so impressed and pleased that you have taken the time and trouble to help.
I will of course fire up eclipse shortly and see if I can get this to work.

Kindest Regards

Jim

Hello Jens

It works beautifully - I’d send images - but uploading them seems to be a problem just now.

Vaadin + Geronimo + JPA + MySql…great stuff.

Sincere thanks to you and all at Vaadin for your patience.

I’m playing Finlandia at full volume

Kindest Regards

Jim

No problem, I’m happy that I was of help. I struggled with understanding the data binding myself when I started using Vaadin. :slight_smile:

Just ask if there is something else seems unclear to you.