When you bind a field, or change the bean, vaadin calls the getter, calls any converters and sets the field value. So far so good.
Then it immediately converts back, and if the value is different it calls the setter
This means that the act of displaying data in an editor can change it.
User gets prompted: “Do you want to save?”, even if she has changed nothing.
IMHO this is objectively bad.
When I bind a form, I believe I can get around this by setting a “ignore writeback” on the bean, and test against that in the setter.
This is really ugly, but it seems to work.
In a grid however, it looks like the binding is set up lazily just before returning to client
So, even if I set a flag around my call to grid.editItem, the flag is off when binder.setBean is actually called and the fields are initialized.
Trying to find a way around this, I see that:
- Binder.setBean calls Binding.initFieldValue(bean, /* writeBackChangedValues → */ true)
- Binding.initFieldValue calls setter if writeBackChangedValues, and converted value is different.
This should’ve been trivial to fix: Create MyBinder extends Binder, override setBean, keep all the code, but replace the “true” with “false”.
Unfortunately, as is often the case with Vaadin, even though setBean itself is public, the things it calls are private, so I can’t do it.
I did a quick experiment with copying all of Binder, but it has other internal dependencie, so it looks like I’m stuck.
The only thing I can think of is to not allow vaadin to edit our data directly:
Ie, the getter/setter we give to vaadin is for the finished display value; We can not use Vaadin’s converters.