JPA 2.0 - Which container?

Hi,

I’m new to Vaadin and have some problems figuring out how to use JPA 2.0.

All I want to do is show the JPA-based user objects in a table.

Here’s my User class:

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import static javax.persistence.GenerationType.IDENTITY;
import javax.persistence.Id;
import javax.persistence.Table;


@Entity
@Table(name = "user", catalog = "test")
public class User implements java.io.Serializable {

    @Id
    @GeneratedValue(strategy = IDENTITY)
    @Column(name = "id", unique = true, nullable = false)
    private Integer id;
    @Column(name = "username", length = 45)
    private String username;
    @Column(name = "password", length = 45)
    private String password;


    protected User() {
    }

    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }

    public Integer getId() {
        return this.id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return this.username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return this.password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

I could query all User objects with my EntityManager and then add those objects to the table but I want to do it the right way.

From what I’ve learned, there are specialised containers such as HbnContainer, but this is Hibernate specific.

Can someone give me some hints on how to correctly use JPA 2.0 with a Vaadin table?

If you want simple JPA 2.0 support, you can try the
JPA 2.0 Criteria LazyQueryContainer
from the add-ons.

If you want to associate an entity with your container, you can use

cd = new CriteriaQueryDefinition<Task>(entityManager,true,100,Task.class);
CriteriaContainer<Task> taskContainer = new CriteriaContainer<Task>(cd);

(this will load the entity Task lazily, with a batch size of 100).

You can subclass CriteriaQueryDefinition to do arbitrarily sophisticated queries, or use the simple filtering mechanism provided.

Hi Jean-François Lamy. First of all, Many thanks by the JPA2 Container. It looks great, and means to be very extensible. Im making my first tests, and I wanna use it in a new project, but, i’m having some problems with the property ids of the container.

My Code:


private Container gridContainer;

private void configureGrid() {
        loadContainer();
        gridUsuarios.setContainerDataSource(gridContainer);
        
        gridUsuarios.addGeneratedColumn("accountLocked", new ColumnGenerators.BooleanColumnGenerator());
        gridUsuarios.setColumnAlignment("accountLocked", Table.ALIGN_CENTER);
        gridUsuarios.addGeneratedColumn("expirationDate", new ColumnGenerators.DateColumnGenerator());
        
        // Configurando colunas e nomes
        String[] colunasVisiveis = new String[]
 {"name", "username", "email", "accountLocked", "expirationDate", "failedLoginAttempts", "failedPasswordChanges"};
        gridUsuarios.setColumnHeader("name", "Nome");
        gridUsuarios.setColumnHeader("username", "Login");
        gridUsuarios.setColumnHeader("email", "Email");
        gridUsuarios.setColumnHeader("accountLocked", "Conta Bloqueada");
        gridUsuarios.setColumnHeader("expirationDate", "Validade da Conta");
        gridUsuarios.setColumnHeader("failedLoginAttempts", "Falhas de Login");
        gridUsuarios.setColumnHeader("failedPasswordChanges", "Trocas de Senha Falhas");
        
        gridUsuarios.setVisibleColumns(colunasVisiveis);
}

private void loadContainer() {
        CriteriaQueryDefinition<User> cd = new CriteriaQueryDefinition<User>(controller.getDaoEntityManager(), true, 50, User.class);
        gridContainer = new CriteriaContainer<User>(cd);
    }

When try load the grid, I have this error:


Caused by: java.lang.IllegalArgumentException: Ids must exist in the Container or as a generated column , missing id: name

I Need to set the ids on container, or it will get the ids by reflection?

Many thanks by help

You do not need to add properties to the container.

You can see the properties that the container thinks it has by adding a trace with gridContainer.getContainerPropertyIds()

The container properties are obtained from the JPA 2.0 metamodel. In the current version, the properties added are those for regular attributes (since “name” is propably a String property in the entity, it should be there). In other words,
they would be

Set<?> attributes = entityManager.getMetamodel().entity(User.class).getSingularAttributes(); If you want, you can override extend CriteriaQueryDefinition and override the addEntityProperties method.

I suggest that you confirm that JPA 2 thinks there is a “name” field in your entity. You should be able to see “name” in the generated User_.java file (which is the generated static metamodel file that JPA2 creates).

Looking at your earlier code, you have no property called “name”
Your property is called “username”, and things should work if you spell the property exactly as in your code.

Hi Jean-François. Many thanks by your attention!

Im a beginner in JPA 2.0. I’ve seen many examples, using metamodels, but in true, I was not using it. Now, im generating automatically metamodel with the Hibernate metamodel generator, and now I will make a test.

This is my Entity Class:



package br.com.simus.supera.ciclonev2.persistence.sistema;

import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;

import br.com.simus.supera.ciclonev2.persistence.DefaultEntity;

/**
 * Classe de Entidade para representacao de usuarios
 * 
 * @author eduardo.frazao
 * Creditos mantidos para KIM, Vaddin AppFoundation Addon (http://code.google.com/p/vaadin-appfoundation/)
 * 
 */
@Entity
@Table(name = "t001_usuarios", uniqueConstraints = { @UniqueConstraint(columnNames = { "t001_username" }) })
@SequenceGenerator(name="t001_sistema_t001_usuario_iu_seq", sequenceName = "t001_sistema_t001_usuario_iu_seq", allocationSize = 1, initialValue = 1)
public class User extends DefaultEntity<Integer> implements br.com.simus.supera.vaadinfoundation.auth.User<Integer> {

    /**
     * 
     */
    private static final long serialVersionUID = -5056844479542871913L;

    @Id
    @GeneratedValue(generator="t001_sistema_t001_usuario_iu_seq", strategy=GenerationType.AUTO)
    @Column(name="t001_usuario_iu")
    private Integer id;
    
    @Column(name="t001_username")
    protected String username;

    @Column(name="t001_password")
    protected String password;

    @Column(name="t001_nome")
    private String name;
    
    @Column(name="t001_email")
    private String email;

    @Column(name="t001_tentativas_login_falhas")
    private Integer failedLoginAttempts = 0;

    @Column(name="t001_conta_bloqueada", nullable=false)
    private boolean accountLocked = false;

    @Column(name="t001_motivo_bloqueio")
    private String reasonForLockedAccount;

    @Column(name="t001_tentativas_falhas_troca_senha")
    private Integer failedPasswordChanges = 0;
    
    @Column(name="t001_max_tentativas_login")
    private Integer maxFailedPasswordChanges = 0;
    
    @Column(name="t001_validade_conta")
    private Date expirationDate;
    
    @Column(name="t001_deve_trocar_senha")
    private boolean forcedToChangePass = false;
    
    @Column(name="t001_adminuser", nullable=false)
    private boolean adminUser = false;
    
    @Column(name="t001_superuser", nullable=false)
    private boolean superUser = false;
    
    @Column(name="t001_proprietario", nullable=false)
    private boolean proprietario = false;
    
    @Column(name="t001_executor_tarefas", nullable=false)
    private boolean executorDeTarefas = false;
    
    @Column(name="t001_comprador", nullable=false)
    private boolean comprador = false;
    
    public User() {

    }

     // Getters and Setters
    
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = super.hashCode();
        result = prime * result + ((id == null) ? 0 : id.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (!super.equals(obj)) {
            return false;
        }
        if (!(obj instanceof User)) {
            return false;
        }
        User other = (User) obj;
        if (id == null) {
            if (other.id != null) {
                return false;
            }
        } else if (!id.equals(other.id)) {
            return false;
        }
        return true;
    }

}





package br.com.simus.supera.ciclonev2.persistence.sistema;

import java.util.Date;

import javax.persistence.metamodel.SingularAttribute;

import javax.persistence.metamodel.StaticMetamodel;


@StaticMetamodel(User.class)
public abstract class User_ {

	public static volatile SingularAttribute<User, Boolean> proprietario;
	public static volatile SingularAttribute<User, Date> expirationDate;
	public static volatile SingularAttribute<User, String> reasonForLockedAccount;
	public static volatile SingularAttribute<User, Boolean> executorDeTarefas;
	public static volatile SingularAttribute<User, Boolean> forcedToChangePass;
	public static volatile SingularAttribute<User, Boolean> superUser;
	public static volatile SingularAttribute<User, String> password;
	public static volatile SingularAttribute<User, Boolean> accountLocked;
	public static volatile SingularAttribute<User, Integer> id;
	public static volatile SingularAttribute<User, String> username;
	public static volatile SingularAttribute<User, String> email;
	public static volatile SingularAttribute<User, Integer> failedLoginAttempts;
	public static volatile SingularAttribute<User, Boolean> adminUser;
	public static volatile SingularAttribute<User, Boolean> comprador;
	public static volatile SingularAttribute<User, String> name;
	public static volatile SingularAttribute<User, Integer> failedPasswordChanges;
	public static volatile SingularAttribute<User, Integer> maxFailedPasswordChanges;

}

I will try now, and will post the result here!

Thanks again

HI Jean-François Lamy.

The property names are right, and even with the MetaModel, the container does not recognize them. If I add the property on container manually, it works.

Im doing something wrong?
The metamodel is in the same package as the Entity Classes, with the same name, followed by a “_”

Att,
Eduardo Frazão

I took your code and created a test application with it. I am not able to reproduce your missing property behavior.
I have uploaded a working war (with all its libraries), the corresponding source files, and the test Eclipse project to the URL
http://goo.gl/V2WRA

However, there was something not expected: your User entity is not a bean (there are no getters and setters for your private properties, and Eclipse gives warnings on all the definitions). LazyQueryContainer (and my JPA 2 extensions) expect entities to be beans (because they are wrapping the entity as BeanItems or a close equivalent). I just generated setters and getters for your entity and things work as expected when I do. If there are no getters, I just get empty rows (but not your missing property behavior).

If you spot the difference do tell me about it; it is likely some trivial oversight.

Sorry by my mistake Jean. I forgot to say that I have supressed the Getters and Setter on the posted code. The Bean haves getters and setters. I only removed it from the post, to reduce the size of message.

Anyway, I will see your project, and try to find what is wrong. Im using the CriteriaContainer right now, and it is working, but I need to add the properties manually.

Do you want the complete code of the Entity?

I can show you another entity that Im using CriteriaContainer.

Again, huge thanks by your help!

Hi Jean. I’ve see your test project, and I dont see any differences on your code :(.

Im using your container with success, but, Im adding manually the properties.

Here is a working example:

Entity:


package br.com.simus.supera.ciclonev2.persistence.jobs;

import java.util.Date;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import br.com.simus.supera.ciclonev2.persistence.DefaultEntity;

@Entity
@Table(name="t010_jobs")
@SequenceGenerator(name="t010_jobs_t010_job_iu_seq", sequenceName="t010_jobs_t010_job_iu_seq", allocationSize=1, initialValue=1)
public class Job extends DefaultEntity<Long>{

    /**
     * 
     */
    private static final long serialVersionUID = 3661148088304105164L;

    @Id
    @Column(name="t010_job_iu")
    @GeneratedValue(generator="t010_jobs_t010_job_iu_seq", strategy=GenerationType.AUTO)
    private Long id;
    
    @Column(name="t010_job_name", nullable=false)
    private String jobName;
    
    @Column(name="t010_job_class", nullable=false)
    private String jobClass;
    
    @Column(name="t010_data_inicio", nullable=false)
    @Temporal(TemporalType.TIMESTAMP)
    private Date dataInicio;
    
    @Column(name="t010_data_termino")
    @Temporal(TemporalType.TIMESTAMP)
    private Date dataTermino;
    
    @OneToOne(cascade={CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE}, mappedBy="job", fetch=FetchType.LAZY)
    private TriggerSegundos triggerSegundos;

    @OneToOne(cascade={CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE}, mappedBy="job", fetch=FetchType.LAZY)
    private TriggerMinutos triggerMinutos;
    
    @OneToOne(cascade={CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE}, mappedBy="job", fetch=FetchType.LAZY)
    private TriggerHoras triggerHoras;
    
    @OneToOne(cascade={CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE}, mappedBy="job", fetch=FetchType.LAZY)
    private TriggerDiaria triggerDiaria;
    
    @OneToOne(cascade={CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE}, mappedBy="job", fetch=FetchType.LAZY)
    private TriggerSemanal triggerSemanal;
    
    @OneToOne(cascade={CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE}, mappedBy="job", fetch=FetchType.LAZY)
    private TriggerMensal triggerMensal;
    
    @OneToOne(cascade={CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE}, mappedBy="job", fetch=FetchType.LAZY)
    private TriggerCron triggerCron;
    
    // Tarefas
    @OneToOne(cascade={CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE}, mappedBy="job", fetch=FetchType.LAZY)
    private JobSentencaSQL jobSentencaSql;
    
    // Actions
    @OneToOne(cascade={CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REMOVE}, mappedBy="job", fetch=FetchType.LAZY)
    private ActionEmail actionEmail;
    
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getJobName() {
        return jobName;
    }

    public void setJobName(String jobName) {
        this.jobName = jobName;
    }

    public String getJobClass() {
        return jobClass;
    }

    public void setJobClass(String jobClass) {
        this.jobClass = jobClass;
    }

    public Date getDataInicio() {
        return dataInicio;
    }

    public void setDataInicio(Date dataInicio) {
        this.dataInicio = dataInicio;
    }

    public Date getDataTermino() {
        return dataTermino;
    }

    public void setDataTermino(Date dataTermino) {
        this.dataTermino = dataTermino;
    }

    public TriggerSegundos getTriggerSegundos() {
        return triggerSegundos;
    }

    public void setTriggerSegundos(TriggerSegundos triggerSegundos) {
        this.triggerSegundos = triggerSegundos;
    }

    public TriggerMinutos getTriggerMinutos() {
        return triggerMinutos;
    }

    public void setTriggerMinutos(TriggerMinutos triggerMinutos) {
        this.triggerMinutos = triggerMinutos;
    }

    public TriggerHoras getTriggerHoras() {
        return triggerHoras;
    }

    public void setTriggerHoras(TriggerHoras triggerHoras) {
        this.triggerHoras = triggerHoras;
    }

    public TriggerDiaria getTriggerDiaria() {
        return triggerDiaria;
    }

    public void setTriggerDiaria(TriggerDiaria triggerDiaria) {
        this.triggerDiaria = triggerDiaria;
    }

    public TriggerSemanal getTriggerSemanal() {
        return triggerSemanal;
    }

    public void setTriggerSemanal(TriggerSemanal triggerSemanal) {
        this.triggerSemanal = triggerSemanal;
    }

    public TriggerMensal getTriggerMensal() {
        return triggerMensal;
    }

    public void setTriggerMensal(TriggerMensal triggerMensal) {
        this.triggerMensal = triggerMensal;
    }

    public TriggerCron getTriggerCron() {
        return triggerCron;
    }

    public void setTriggerCron(TriggerCron triggerCron) {
        this.triggerCron = triggerCron;
    }

    public ActionEmail getActionEmail() {
        return actionEmail;
    }

    public void setActionEmail(ActionEmail actionEmail) {
        this.actionEmail = actionEmail;
    }

    public JobSentencaSQL getJobSentencaSql() {
        return jobSentencaSql;
    }

    public void setJobSentencaSql(JobSentencaSQL jobSentencaSql) {
        this.jobSentencaSql = jobSentencaSql;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = super.hashCode();
        result = prime * result + ((id == null) ? 0 : id.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (!super.equals(obj)) {
            return false;
        }
        if (!(obj instanceof Job)) {
            return false;
        }
        Job other = (Job) obj;
        if (id == null) {
            if (other.id != null) {
                return false;
            }
        } else if (!id.equals(other.id)) {
            return false;
        }
        return true;
    }    
}

MetaModel:


package br.com.simus.supera.ciclonev2.persistence.jobs;

import java.util.Date;
import javax.persistence.metamodel.SingularAttribute;
import javax.persistence.metamodel.StaticMetamodel;

@StaticMetamodel(Job.class)
public abstract class Job_ {

	public static volatile SingularAttribute<Job, Date> dataTermino;
	public static volatile SingularAttribute<Job, TriggerMinutos> triggerMinutos;
	public static volatile SingularAttribute<Job, TriggerHoras> triggerHoras;
	public static volatile SingularAttribute<Job, String> jobName;
	public static volatile SingularAttribute<Job, TriggerDiaria> triggerDiaria;
	public static volatile SingularAttribute<Job, String> jobClass;
	public static volatile SingularAttribute<Job, TriggerSegundos> triggerSegundos;
	public static volatile SingularAttribute<Job, Long> id;
	public static volatile SingularAttribute<Job, Date> dataInicio;
	public static volatile SingularAttribute<Job, TriggerCron> triggerCron;
	public static volatile SingularAttribute<Job, ActionEmail> actionEmail;
	public static volatile SingularAttribute<Job, JobSentencaSQL> jobSentencaSql;
	public static volatile SingularAttribute<Job, TriggerSemanal> triggerSemanal;
	public static volatile SingularAttribute<Job, TriggerMensal> triggerMensal;

}

Code using the Container:


    @Override
    public Container loadGridContainer() {
        JobController controller = new JobController();
        CriteriaQueryDefinition<Job> cd = new CriteriaQueryDefinition<Job>(controller.getDaoEntityManger(), true, 50, Job.class);
        CriteriaContainer<Job> container = new CriteriaContainer<Job>(cd);
        container.addContainerProperty("jobName", String.class, null, false, true);
        container.addContainerProperty("dataInicio", Date.class, null, false, true);
        container.addContainerProperty("dataTermino", Date.class, null, false, true);
        return container;
    }
    
    @Override
    protected void gridPosConfig() {
        getGrid().addGeneratedColumn("jobEstado", new JobEstadoGenerator());
        getGrid().addGeneratedColumn("dataInicio", new ColumnGenerators.DateColumnGenerator());
        getGrid().addGeneratedColumn("dataTermino", new ColumnGenerators.DateColumnGenerator());
        getGrid().addGeneratedColumn("ultimaExecucao", new jobUltimaExecucao());
        getGrid().addGeneratedColumn("proximaExecucao", new jobProximaExecucao());
        
        getGrid().setColumnHeader("jobName", "Tarefa");
        getGrid().setColumnHeader("jobEstado", "Estado da Tafera");
        getGrid().setColumnHeader("dataInicio", "Início da Tarefa");
        getGrid().setColumnHeader("dataTermino", "Fim da Tarefa");
        getGrid().setColumnHeader("ultimaExecucao", "Última execução");
        getGrid().setColumnHeader("proximaExecucao", "Próxima execução");
        
        getGrid().setVisibleColumns(new String[] {"jobName", "jobEstado", "dataInicio", "dataTermino", "ultimaExecucao", "proximaExecucao"});
        
        configureGridContextMenu();
    }

This code is working, but I need to add the Container Properties.
The metamodel definition is in the same package as the Entity. Only the compiled metamodel is present.

This is a test code, trying to read the property names, base on the metamodel:


Set<SingularAttribute<? super Job, ?>> attrs = controller.getDaoEntityManger().getMetamodel().entity(Job.class).getSingularAttributes();
        
        Iterator<SingularAttribute<? super Job, ?>> i = attrs.iterator(); 
        while(i.hasNext()) {
            System.out.println(i.next().getName());
        }

Output:


triggerHoras
triggerDiaria
triggerCron
actionEmail
triggerSemanal
triggerMinutos
triggerMensal
jobName
jobSentencaSql
dataTermino
triggerSegundos
dataInicio
id
jobClass

Something is wrong in this model? There any additional configuration for the container locate the MetaModel definition?

Many thanks!

The code inside the container does exactly the same loop as the one you posted, it calls getMetamodel(). My suggestions regarding the static metamodel where just an additional verification.

  1. Can you make sure that you are using a recent jar (0.4.1 or 0.4.2) (take the one in the war I posted to be sure) – earlier versions of the jar did not add properties automatically

  2. In your code, can you check, immediately after obtaining the container, that all went well by printing the property ids (using getContainerPropertyIds)

  3. Finally, you can download the source for CriteriaQueryDefinition (use this
    link
    ) , and add it to your project (just create an org.vaadin.addons.criteriacontainer package and copy the class there). Then you can add traces or breakpoints in the addEntityProperties() method. As you can plainly see, it calls the exact same loop as the one you used for traces, so there is no reason that the properties would go away.

4 Can you run my war and see if it works in your environment (it should run as is, because I used a Derby database, but after an initial test with Derby you can change persistence.xml to match your own database).

Sorry for the trouble, I’d really like for us to figure out what is causing you grief.

Hi Jean

Im using the 0.4.2 version (criteriacontainer-0.4.2.jar)

Yes. No property is added:


CriteriaQueryDefinition<Job> cd = new CriteriaQueryDefinition<Job>(controller.getDaoEntityManger(), true, 50, Job.class);
        CriteriaContainer<Job> container = new CriteriaContainer<Job>(cd);
        System.out.println(container.getContainerPropertyIds().size());
        for(Object id : container.getContainerPropertyIds()) {
            System.out.println(id.toString());
        }

Output: (None is added to Collection of property ids)


0

Ive made that, and discover that exist some incompatible things with the version 0.4.2 and the Lazy Container 1.2.7.
With downgrade to 1.2.6 I can compile the CriteriaContainer.
I put breakpoints on the method that you say, and it is working. The method can read the properties, because, I can see the contents of the variables, but for some reason, they arent avaliable on the container.

Your project works fine… I dont know what is wrong with my code. Im using Hibernate 3.5.6. Its the only difference from your setup…
Only one observation. In the code of your application, i’ve put this code to read properties name:


 protected CriteriaContainer<User> createUserContainer() {
        CriteriaQueryDefinition<User> cd = new CriteriaQueryDefinition<User>(entityManager,true,100,User.class);      
        CriteriaContainer<User> taskContainer = new CriteriaContainer<User>(cd);
	
	System.out.println(taskContainer.getContainerPropertyIds().size());
        for(Object id : taskContainer.getContainerPropertyIds()) {
            System.out.println(id.toString());
	}

        return taskContainer;
    }

And, none property is returned on the collection… Only the size, wich is 0.
But, if I put this code, on your createTable method, the properties exists…

And theres no problem. Its me that want to thank you by your time, and your great contribuition with this container!

Ive created a button, that set the visible columns. The grid initially loads without the columns, but when I click the button, it works. This set the columns to show, and the grid is refreshed with the values.

It appears that on the first render of the table, the properties does not exist yet.

The container and the table is loaded on the constructor method.

Strange :unsure:

Interesting information. The code tries to avoid repeating queries and in general be lazy about its initialization, maybe I missed a limit case, and it might be linked with the properties vanishing act.

There is a method container.refresh(). In theory, you should not need it, but it might provide a workaround until I figure out what is going on (I am hoping to work on this over the weekend). Your button could force a call to refresh().

Jean, you are right. Calling the refresh() method immeditatelly after create the container works.
If you release another version of the container after weekend, I will be hapy to test it on my case!!!

And again, many thanks by your effort!

What do you think about to create a POST in the Add-ons category, to discussions related to the Criteria Container, and link it in the Add-on page?

Att,
Eduardo Frazão

Good suggestion. Will do once I finish my little fight with the container. I have been able to reproduce both your problems (or more precisely, a colleague’s code turned out to have the same issues). I have fixed the vanishing property issue. I am trying to see what is going on with the empty tables.

Oh, good news!!! :slight_smile:

Unfortunatelly, im a newbe on Vaadin. Even In Java i belive. Im studing your container code, but I dont have a clear idea yeat, to try to help you. If I can help with tests, I will be happy!

Thanks again by your effort.

Att,
Eduardo Frazão