I am new to Vaadin and on a tight deadline so I am hoping someone can help me understand what is going on here. I have a form and using BeanFieldGroup but when I call commit it blows up with com.vaadin.data.fieldgroup.FieldGroup$CommitException: Property “brand” not bound to datasource.
This is my backing object.
public class ParameterFormDto {
private Brand brand;
private Category category;
private SubCategory subCategory;
private MasterParameter masterParameter;
private ParameterLevel parameterLevel;
private String levelValue;
private String order;
private String value;
private Date effectiveStartDate;
private Date effectiveEndDate;
public ParameterFormDto() {
}
public Brand getBrand() {
return brand;
}
public void setBrand(Brand brand) {
this.brand = brand;
}
public Category getCategory() {
return category;
}
public void setCategory(Category category) {
this.category = category;
}
public SubCategory getSubCategory() {
return subCategory;
}
public void setSubCategory(SubCategory subCategory) {
this.subCategory = subCategory;
}
public MasterParameter getMasterParameter() {
return masterParameter;
}
public void setMasterParameter(MasterParameter masterParameter) {
this.masterParameter = masterParameter;
}
public ParameterLevel getParameterLevel() {
return parameterLevel;
}
public void setParameterLevel(ParameterLevel parameterLevel) {
this.parameterLevel = parameterLevel;
}
public String getLevelValue() {
return levelValue;
}
public void setLevelValue(String levelValue) {
this.levelValue = levelValue;
}
public String getOrder() {
return order;
}
public void setOrder(String order) {
this.order = order;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public Date getEffectiveStartDate() {
return effectiveStartDate;
}
public void setEffectiveStartDate(Date effectiveStartDate) {
this.effectiveStartDate = effectiveStartDate;
}
public Date getEffectiveEndDate() {
return effectiveEndDate;
}
public void setEffectiveEndDate(Date effectiveEndDate) {
this.effectiveEndDate = effectiveEndDate;
}
}
And this is my form code.
@SpringComponent
@UIScope
public class AddParameterForm extends FormLayout {
private static final Logger logger = LoggerFactory.getLogger(AddParameterForm.class);
private final ParameterService parameterService;
private BeanFieldGroup<ParameterFormDto> formFieldBindings = new BeanFieldGroup<>(ParameterFormDto.class);
// ui memebers
@PropertyId("brand")
public NativeSelect brand;
private NativeSelect category;
private NativeSelect subCategory;
private NativeSelect parameter;
private NativeSelect level;
private TextField levelValue;
private TextField order;
private TextField value;
private PopupDateField effectiveStart;
private PopupDateField effectiveEnd;
private Button cancelButton;
private Button saveButton;
// data members
private Brand selectedBrand;
private Category selectedCategory;
private SubCategory selectedSubCategory;
private MasterParameter selectedParameter;
private ParameterLevel selectedParameterLevel;
@Autowired
public AddParameterForm(ParameterService parameterService) {
this.parameterService = parameterService;
initUserInterface();
}
private void initUserInterface() {
setVisible(false);
setMargin(true);
setSizeFull();
//formFieldBindings = new BeanFieldGroup<>(ParameterFormDto.class);
// initialize ui components
brand = new NativeSelect("Brand");
brand.setEnabled(true);
category = new NativeSelect("Category");
category.setEnabled(false);
subCategory = new NativeSelect("Sub Category");
subCategory.setEnabled(false);
parameter = new NativeSelect("Parameter");
parameter.setEnabled(false);
level = new NativeSelect("Level");
level.setEnabled(false);
levelValue = new TextField("Level Value");
order = new TextField("Order");
value = new TextField("Value");
effectiveStart = new PopupDateField("Effective Start");
effectiveEnd = new PopupDateField("Effective End");
cancelButton = new Button("Cancel", event -> {
logger.debug("user cancelled adding parameter");
formFieldBindings.discard();
setVisible(false);
closeParentWindow();
Notification.show("Cancelled", Notification.Type.TRAY_NOTIFICATION);
});
saveButton = new Button("Save", event -> {
try {
formFieldBindings.commit();
ParameterFormDto parameter = formFieldBindings.getItemDataSource().getBean();
parameterService.save(parameter);
setVisible(false);
closeParentWindow();
Notification.show("Parameter saved successfully", Notification.Type.TRAY_NOTIFICATION);
}
catch (FieldGroup.CommitException e) {
Notification.show("Error while saving parameter", Notification.Type.ERROR_MESSAGE);
logger.error("Error saving parameter", e);
}
});
effectiveStart.setDateFormat("MM/dd/yyyy HH:mm");
effectiveStart.setResolution(Resolution.MINUTE);
effectiveEnd.setDateFormat("MM/dd/yyyy HH:mm");
effectiveEnd.setResolution(Resolution.MINUTE);
// validation logic
effectiveStart.addValidator((Validator) value1 -> {
if (value1 == null) {
throw new Validator.InvalidValueException("Effective Start Time cannot be null");
}
try {
java.util.Calendar cal = java.util.Calendar.getInstance();
cal.setTime((Date) value1);
} catch (Exception e) {
throw new Validator.InvalidValueException("Effective Start Time is invalid");
}
});
order.addValidator(value1 -> {
if (value1 == null) {
throw new Validator.EmptyValueException("Order cannot be blank");
}
//if (Integer.parseInt((String) value1) < 0) {
// throw new Validator.InvalidValueException("Order can't be negative");
//}
});
value.addValidator(value1 -> {
if (value1 == null || value1.equals("")) {
throw new Validator.EmptyValueException("Please provide a parameter value");
}
});
levelValue.addValidator(value1 -> {
if (value1 == null || value1.equals("")) {
throw new Validator.EmptyValueException("Please provide a level value");
}
});
effectiveEnd.addValidator(value1 -> {
if (value1 != null) {
java.util.Calendar today = java.util.Calendar.getInstance();
today.set(java.util.Calendar.MINUTE, 0);
today.set(java.util.Calendar.SECOND, 0);
today.set(java.util.Calendar.HOUR_OF_DAY, 0);
if (((Date) value1).getTime() < today.getTimeInMillis()) {
throw new Validator.InvalidValueException("Effective end time cannot be in the past");
}
}
});
BeanItemContainer<Brand> brandBeanItemContainer =
new BeanItemContainer<Brand>(Brand.class, parameterService.getBrands());
BeanItemContainer<Category> categoryBeanItemContainer =
new BeanItemContainer<Category>(Category.class, parameterService.getCategories());
BeanItemContainer<ParameterLevel> parameterLevelBeanItemContainer =
new BeanItemContainer<ParameterLevel>(ParameterLevel.class, parameterService.getLevels());
level.setContainerDataSource(parameterLevelBeanItemContainer);
level.setItemCaptionPropertyId("level");
level.addValueChangeListener(event -> {
ParameterLevel parameterLevel = (ParameterLevel) event.getProperty().getValue();
if (parameterLevel != null && parameterLevel.getId() == 1) {
levelValue.setValue("ANY");
levelValue.setReadOnly(true);
}
else if (parameterLevel != null && parameterLevel.getId() > 1) {
levelValue.setReadOnly(false);
levelValue.setValue("");
}
});
brand.setContainerDataSource(brandBeanItemContainer);
brand.setItemCaptionPropertyId("name");
brand.addValueChangeListener(event -> {
selectedBrand = (Brand) event.getProperty().getValue();
if (selectedBrand != null) {
category.setEnabled(true);
category.setContainerDataSource(categoryBeanItemContainer);
category.setItemCaptionPropertyId("category");
}
});
category.addValueChangeListener(event -> {
selectedCategory = (Category) event.getProperty().getValue();
if (selectedCategory != null) {
subCategory.setEnabled(true);
BeanItemContainer<SubCategory> subCategoryBeanItemContainer =
new BeanItemContainer<SubCategory>(SubCategory.class,
parameterService.getSubCategories(selectedCategory.getId()));
subCategory.setContainerDataSource(subCategoryBeanItemContainer);
subCategory.setItemCaptionPropertyId("subCategory");
}
});
subCategory.addValueChangeListener(event -> {
selectedSubCategory = (SubCategory) event.getProperty().getValue();
if (selectedSubCategory != null) {
parameter.setEnabled(true);
BeanItemContainer<MasterParameter> masterParameterBeanItemContainer =
new BeanItemContainer<MasterParameter>(MasterParameter.class,
parameterService.getMasterParam(selectedBrand.getId(), selectedSubCategory.getId()));
parameter.setContainerDataSource(masterParameterBeanItemContainer);
parameter.setItemCaptionPropertyId("parameterName");
}
});
parameter.addValueChangeListener(event -> {
selectedParameter = (MasterParameter) event.getProperty().getValue();
if (selectedParameter != null) {
level.setEnabled(true);
order.setEnabled(true);
value.setEnabled(true);
effectiveStart.setEnabled(true);
effectiveEnd.setEnabled(true);
}
});
formFieldBindings.buildAndBindMemberFields(this);
addComponent(brand);
addComponent(category);
addComponent(subCategory);
addComponent(parameter);
addComponent(level);
addComponent(levelValue);
addComponent(order);
addComponent(value);
addComponent(effectiveStart);
addComponent(effectiveEnd);
HorizontalLayout horizontalLayout = new HorizontalLayout(saveButton, cancelButton);
horizontalLayout.setSpacing(true);
horizontalLayout.setMargin(false);
addComponent(horizontalLayout);
brand.focus();
}
@Override
public MainUI getUI() {
return (MainUI) super.getUI();
}
private void closeParentWindow() {
((AddParameterWindow) super.getParent().getParent()).close();
}
}