From fbbb689925274e0af49df14c5ac05a12759fae31 Mon Sep 17 00:00:00 2001 From: Tatu Lund Date: Wed, 27 Oct 2021 16:36:06 +0300 Subject: [PATCH] fix: don't update bean property which is read-only bound (#12457) --- .../src/main/java/com/vaadin/data/Binder.java | 2 +- .../test/java/com/vaadin/data/BinderTest.java | 71 +++++++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/server/src/main/java/com/vaadin/data/Binder.java b/server/src/main/java/com/vaadin/data/Binder.java index e969a032f7..9726f54345 100644 --- a/server/src/main/java/com/vaadin/data/Binder.java +++ b/server/src/main/java/com/vaadin/data/Binder.java @@ -1258,7 +1258,7 @@ public class Binder implements Serializable { TARGET originalValue = getter.apply(bean); convertAndSetFieldValue(originalValue); - if (writeBackChangedValues && setter != null) { + if (writeBackChangedValues && setter != null && !readOnly) { doConversion().ifOk(convertedValue -> { if (!Objects.equals(originalValue, convertedValue)) { setter.accept(bean, convertedValue); diff --git a/server/src/test/java/com/vaadin/data/BinderTest.java b/server/src/test/java/com/vaadin/data/BinderTest.java index 62ac93ce8e..9f20f0b246 100644 --- a/server/src/test/java/com/vaadin/data/BinderTest.java +++ b/server/src/test/java/com/vaadin/data/BinderTest.java @@ -10,6 +10,7 @@ import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import java.io.Serializable; import java.math.BigDecimal; import java.text.DecimalFormat; import java.text.NumberFormat; @@ -1540,6 +1541,76 @@ public class BinderTest extends BinderTestBase, Person> { assertEquals("Name", nameField.getValue()); } + @Test + public void setBean_readOnlyBinding_propertyBinding_valueIsNotUpdated() { + Binder binder = new Binder<>(ExampleBean.class); + + binder.forField(nameField).withNullRepresentation("") + .withConverter(new TestConverter()).bind("vals") + .setReadOnly(true); + + ExampleBean bean = new ExampleBean(); + SubPropClass val = new SubPropClass(); + bean.setVals(val); + binder.setBean(bean); + + assertSame(val, bean.getVals()); + } + + @Test + public void setBean_readOnlyBinding_accessorsBiding_valueIsNotUpdated() { + Binder binder = new Binder<>(ExampleBean.class); + + binder.forField(nameField).withNullRepresentation("") + .withConverter(new TestConverter()) + .bind(ExampleBean::getVals, ExampleBean::setVals) + .setReadOnly(true); + + ExampleBean bean = new ExampleBean(); + SubPropClass val = new SubPropClass(); + bean.setVals(val); + binder.setBean(bean); + + assertSame(val, bean.getVals()); + } + + public static class ExampleBean implements Serializable { + private SubPropClass vals; + + public SubPropClass getVals() { + return vals; + } + + public void setVals(SubPropClass vals) { + this.vals = vals; + } + } + + public static class SubPropClass implements Serializable { + private String val1 = "Val1"; + + @Override + public String toString() { + return val1; + } + } + + public static class TestConverter + implements Converter { + + @Override + public Result convertToModel(String value, + ValueContext context) { + return Result.ok(null); + } + + @Override + public String convertToPresentation(SubPropClass value, + ValueContext context) { + return value != null ? value.toString() : null; + } + }; + private TextField createNullAnd42RejectingFieldWithEmptyValue( String emptyValue) { return new TextField() { -- 2.39.5