Skip to content

Commit

Permalink
fix: Ensure that side effects of readBean do not set hasChanges true (#…
Browse files Browse the repository at this point in the history
…12181)

JavaDoc of hasChanges says:

"Check whether any of the bound fields' have uncommitted changes
since last explicit call to readBean(Object), removeBean(), writeBean(Object)}
or writeBeanIfValid(Object)."

If readBean has converters, they will be run and field values updated accordingly.
Furthermore if fields have value change listeners that will produce further
changes in values, this should be considered according to above as part of
readBean procedure and thus hasChanges still should return false.

Cherry pick from: vaadin/framework#12455
  • Loading branch information
TatuLund committed Nov 9, 2021
1 parent ad39b06 commit 4e36fd9
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 1 deletion.
Expand Up @@ -2101,7 +2101,6 @@ public void readBean(BEAN bean) {
if (bean == null) {
clearFields();
} else {
changedBindings.clear();
getBindings().forEach(binding -> {
/*
* Some bindings may have been removed from binder during
Expand All @@ -2113,6 +2112,7 @@ public void readBean(BEAN bean) {
binding.initFieldValue(bean, false);
}
});
changedBindings.clear();
getValidationStatusHandler().statusChange(
BinderValidationStatus.createUnresolvedStatus(this));
fireStatusChangeEvent(false);
Expand Down
Expand Up @@ -1968,6 +1968,29 @@ private void setExceptionHandler() {
(field, exception) -> Optional.of(bindingException));
}

// See: https://github.com/vaadin/framework/issues/9581
@Test
public void withConverter_hasChangesFalse() {
TestTextField nameField = new TestTextField();
nameField.setValue("");
TestTextField rentField = new TestTextField();
rentField.setValue("");
rentField.addValueChangeListener(event -> {
nameField.setValue("Name");
});
item.setRent(BigDecimal.valueOf(10));
binder.forField(nameField).bind(Person::getFirstName,
Person::setFirstName);
binder.forField(rentField).withConverter(new EuroConverter(""))
.withNullRepresentation(BigDecimal.valueOf(0d))
.bind(Person::getRent, Person::setRent);
binder.readBean(item);

assertFalse(binder.hasChanges());
assertEquals("€ 10.00", rentField.getValue());
assertEquals("Name", nameField.getValue());
}

private TestTextField createNullRejectingFieldWithEmptyValue(
String emptyValue) {
return new TestTextField() {
Expand Down

0 comments on commit 4e36fd9

Please sign in to comment.