问题
(Sorry if this is a bit of a newb question)
I have two JPAContainers, one for an Employee class/table and one for Language class/table. An employee can have a selected language.
I am trying to create an Employee editing form with a combobox for the language selection and FieldGroup to handle the binding and creation.
I can get the drop down to include the entries from the Languages table via the JPAContainer but it will not display the value already in place in the Employee record. What am I doing wrong?
//Key parts of code....
private JPAContainer<Employee> employees;
private JPAContainer<Language> languages;
FormLayout formLayout = new FormLayout();
formFieldGroup = new FieldGroup(employeeItem);
Field<?> firstName = formFieldGroup.buildAndBind("First name", "firstName");
Field<?> lastName = formFieldGroup.buildAndBind("Last name", "lastName");
Field<?> userName = formFieldGroup.buildAndBind("Username", "userName");
Field<?> fullName = formFieldGroup.buildAndBind("Full name", "fullName");
Field<?> initials = formFieldGroup.buildAndBind("Initials", "initials");
ComboBox language = new ComboBox("Language",languages);
language.setContainerDataSource(languages);
language.setItemCaptionPropertyId("languageName");
language.setFilteringMode(FilteringMode.CONTAINS);
language.setImmediate(true);
formFieldGroup.bind(language, "language");
firstName.addValidator(new BeanValidator(Employee.class, "firstName"));
lastName.addValidator(new BeanValidator(Employee.class, "lastName"));
firstName.addValidator(new BeanValidator(Employee.class, "userName"));
lastName.addValidator(new BeanValidator(Employee.class, "fullName"));
lastName.addValidator(new BeanValidator(Employee.class, "initials"));
formLayout.addComponent(userName);
formLayout.addComponent(fullName);
formLayout.addComponent(firstName);
formLayout.addComponent(lastName);
formLayout.addComponent(initials);
formLayout.addComponent(language);
// A few details of the domain classes
@Entity
@Table(name="Employees")
public class Employee extends BaseEntity
{
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="EmployeeID")
private Integer employeeID;
...
@ManyToOne
@JoinColumn(name="LanguageID",updatable=false)
private Language language;
...}
@Entity
@Table(name="Languages")
public class Language extends BaseEntity
{
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="LanguageID")
private Integer languageID;
@Column(name="LangaugeName")
private String languageName;
... }
回答1:
I received the following response via the Vaadin forums answering this question (Thanks to Jonatan Kronqvist).
Hi Michael,
JPAContainer item IDs are the same as the ID in the database, which means that using a JPAContainer in a select/combo box causes the value of the select to be the ID of the row in the database and not the POJO itself, as is expected by your Employee entity POJO. Adding a SingleSelectConverter to your combo box should fix your problem:
language.setConverter(new SingleSelectConverter(language));
...
HTH, /Jonatan
回答2:
I have written a blog post about this topic: Select Nested JavaBeans With a Vaadin FieldGroup. In this article I try to explain how Vaadin's FieldGroup works internally and how it binds an Item
property to a field component. In the case of trying to select a referenced JavaBean (such as Language
in this question) for an edited Item
, it is important to know how this property binding works, and how to assist that binding with a custom com.vaadin.data.util.converter.Converter
implementation. This also explains from Michael's answer why you need a SingleSelectConverter
in this particular case.
来源:https://stackoverflow.com/questions/15251275/vaadin-7-0-1-combobox-with-jpacontainer-and-fieldgroup