Important Notice - Forums is archived
To simplify things and help our users to be more productive, we have archived the current forum and focus our efforts on helping developers on Stack Overflow. You can post new questions on Stack Overflow or join our Discord channel.

Vaadin lets you build secure, UX-first PWAs entirely in Java.
Free ebook & tutorial.
ComboBox - setItemCaptionMode does not work as expected
Hi everybody,
at the moment, I'm struggling with modelling a 1:n relationship with combo boxes: I have an entitiy "Nutrient" and an entity "NutrientUnit". Each Nutrient can have a NutrientUnit. When I edit the Nutrient, I want to select the NutrientUnit by a combo box. Basically this works fine.
If I try to use setItemCaptionPropertyId, the list in the combo box shows the correct representation from the property I chose. Merely the combobox is not prefilled anymore and stays empty.
Furthermore, if I do not use setItemCaptionPropertyId, the 'toString()' representation is shown (so combobox is filled).
Everybody else like loading and saving to DB works fine.
Can anybody help here ? I tried to reduce everything to an example:
package calculator.ui.view.impl;
import javax.annotation.PostConstruct;
import javax.enterprise.context.SessionScoped;
import javax.inject.Inject;
import calculator.model.db.entities.impl.Nutrient;
import calculator.model.db.entities.impl.NutrientUnit;
import calculator.presenter.impl.NutrientPresenter;
import com.vaadin.data.fieldgroup.BeanFieldGroup;
import com.vaadin.data.fieldgroup.FieldGroup.CommitException;
import com.vaadin.data.util.BeanItem;
import com.vaadin.data.util.BeanItemContainer;
import com.vaadin.ui.AbstractSelect.ItemCaptionMode;
import com.vaadin.ui.Button;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.FormLayout;
import com.vaadin.ui.TextField;
@SessionScoped
@SuppressWarnings("serial")
public class NutrientDetailForm extends CustomComponent {
@Inject
NutrientPresenter presenter;
FormLayout formLayout;
BeanFieldGroup<Nutrient> beanFieldGroup;
BeanItemContainer<NutrientUnit> nutrientUnitContainer;
BeanItem<Nutrient> nutrient = null;
TextField name;
ComboBox nutrientUnit;
Integer id = new Integer(1);
@PostConstruct
public void init() {
formLayout = new FormLayout();
name = new TextField("Name");
nutrientUnit = new ComboBox("Unit");
nutrientUnit.setWidth("1500px");
formLayout.addComponents(name, nutrientUnit);
// create BeanFieldGroup and bind fields
beanFieldGroup = new BeanFieldGroup<Nutrient>(Nutrient.class);
beanFieldGroup.bindMemberFields(this);
// create combo box with all nutrient units
nutrientUnitContainer = new BeanItemContainer<NutrientUnit>(NutrientUnit.class, presenter.getNutrientUnits());
nutrientUnit.setContainerDataSource(nutrientUnitContainer);
nutrientUnit.setItemCaptionMode(ItemCaptionMode.PROPERTY);
nutrientUnit.setItemCaptionPropertyId("unitName");
nutrientUnit.setImmediate(true);
// button to switch between 2 instances of Nutrient (id 1 or 2)
Button b = new Button("Test");
b.addClickListener(e -> loadExample());
Button s = new Button("Save");
s.addClickListener(e -> saveEntity());
formLayout.addComponents(s, b);
setCompositionRoot(formLayout);
}
private void saveEntity() {
try {
beanFieldGroup.commit();
presenter.save(nutrient.getBean());
} catch (CommitException e) {
e.printStackTrace();
}
}
// switches between Nutrient 1 and 2
public void loadExample() {
id++;
nutrient = new BeanItem<Nutrient>(presenter.getEntityById((id % 2) + 1));
beanFieldGroup.setItemDataSource(nutrient);
try {
beanFieldGroup.commit();
} catch (CommitException e) {
e.printStackTrace();
}
}
}
package calculator.model.db.entities.impl;
import java.util.List;
import javax.persistence.Entity;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import calculator.model.db.entities.abstr.AEntity;
@SuppressWarnings("serial")
@Entity
public class Nutrient extends AEntity {
String name;
@OneToMany(mappedBy="nutrient")
List<NutrientValue> nutrientValues;
@ManyToOne
NutrientUnit nutrientUnit;
... /* setters & getters */
//seems not to be considered
@Override
public String toString() {
return this.name;
}
}