How to reflect changes to Bean automatically in bound component?

When I used property datasources in Vaadin 7, changes to the underlying bean field were automatically reflected in the associated UI component.

When I try this with Vaadin 8, it seems I have to explicitly call “readBean”:

       TextField tf = new TextField();

        Binder<Pojo> binder = new Binder<>(Pojo.class);
        binder.bind(tf, "clickTime");

        Button b = new Button("click me");
        b.addClickListener((e) -> {
            pojo.setClickTime(LocalDateTime.now().toString());
            binder.readBean(pojo); // I DO NOT WANT TO DO THIS!
        });
        pojo = new Pojo();
        binder.setBean(pojo);

Is there no way to re-produce the Vaadin 7 behaviour or am I missing something (I just started with Vaadin 8)?

It is sort of feature. But this pull request may be somewhat related: https://github.com/vaadin/framework/commit/a8b09b222ae00e4cf88c02efa67e7c7d89a0eb97

Well, it’s not that different with Vaadin 7:

[code]
TextField tf = new TextField();

pojo = new Pojo();
BeanItem item = new BeanItem<>(pojo);
tf.setPropertyDataSource(item.getItemProperty(“clickTime”));

Button b = new Button(“click me”);
b.addClickListener((e) → {
pojo.setClickTime(“” + LocalDateTime.now().toString());
item.setBean(pojo); // YOU HAVE TO DO THIS!
});
[/code]To be fair you could also do:

item.getItemProperty("clickTime").setValue(LocalDateTime.now().toString()); But that’s so not type-safe!

Anyway, There’s no way for the framework to know when a setter has been called. With Vaadin 7 you have the not type-safe
Property
abstraction through which you can indirectly call the setter, but there’s no such thing in 8 (fortunately), so you have to inform the framework when any of your setters have been called (and that can be done through the
readBean
or
setBean
methods (in your case you’d probably prefer
setBean
, btw).

Also, remember that you can make V8 binding completely type-safe:

binder.bind(tf, Pojo::getClickTime, Pojo::setClickTime);

Yes, you are right. I have to (one way or the other) notify the framework about changes in the underlying bean (I misremembered that regarding Vaadin 7).

Where I disagree is that this is always a good thing. Consider this simplified situation:

TextField tf = new TextField();

Binder<Pojo> binder = new BeanValidationBinder<>(Pojo.class);
binder.bind(tf, Pojo::getSomeProperty, Pojo::setSomeProperty);

Button b = new Button("Trigger Business Logic which may or may not change one of the Pojos properties");

b.addClickListener((e) -> {
   businessLogicService.executeSomeBusinessLogic(pojo);
   binder.readBean(pojo); //I still don't want to do this. Not even in a presenter and coupled by CDI events
});

pojo = new Pojo();
binder.setBean(pojo);

Thing is, I have to introduce a dependency, i.e. knowledge about the effects of the executed business logic (whether and which properties it might change).

And it doesn’t really matter if this dependency is encapsulated in a “Presenter”, “Controller” or any other kind of mediator object/layer. It is always an additional and unnecessary dependency which increases coupling.

Probably this is not a problem in relatively static input forms. However, I often work on projects which are very data centric with lots of input fields (dozens on a single form) and complex business rules regarding validation, required fields, edit/read rights, business process etc.
Often, the same fields can
either
be filled in manually
or interactively
be updated by business logic.

In this scenario, an “automatic refresh” of bound user input components due to business logic interactions would be very helpful in order to avoid bloated “Presenters”.

I remember now how we did it in Vaadin 7. We kind of used a wrapper around the data objects which automatically triggered the refresh of the UI components.

Right, that sounds like a different question. I think this is still debatable, for example, assuming the signature of
executeSomeBusinessLogic
is
executeSomeBusinessLogic(Pojo

pojo

)
, clients cannot assume
pojo
won’t be changed. So there’s no extra “knowledge” leaked here. If it was
executeSomeBusinessLogic(
final
Pojo

pojo

)
, clients know it won’t be changed for sure. If the method returned a
Pojo
, then clients would know they might want to do something with it (e.g. update the UI).

But anyway, right now I can only think of an aspect-oriented technique (to “automatically” call
binder.setBean
), or a, probably a bit intrusive, “bean property change listener” such as the one offered by Java’s

PropertyChangeSupport

. Please share your thoughts on this or if you have an idea on how to achieve the “automátic” update of the UI “onBeanPropertiesValueChange”.

Hi Alejandro,

I am sorry that it took me so long to respond. I have been pondering the raised questions and evaluated some different approaches and finally came to the ultimate conclusion :wink:

The short answer is: I was trying to solve a problem which does not exist anymore.

Let me explain the background a little bit more: During the last years with Vaadin 7, we have put quite some effort into the concept of loose coupling between UI and Business Logic while allowing as much UI/BL-interactivity as possible without the need for “presenters” and similar concepts. The latter always tend to “know” to much about the actual business logic. We wanted to make sure, the complete business logic is really and completely independent of the UI and thus also usable through service interfaces, in automated jobs or as a means of data migration (the latter happened to be an unexpected and very welcome benefit in serveral projects).

Therefore, we are using an abstraction layer which expresses Business Logic in terms of “Business Objects (BOTs)”, “Business Object Attributes”, “Business Object Operations” and generic “Life Cycles” which relate to a certain BOT or a cross-BOT-workflow.

The Vaadin (AbstractField) components we use, are usually bound to BOT-Attributes and only indirectly to entities/DTOs). In order to enable automatic data binding, validation of business rules, automated triggering of functionality via BOT-Operations, workflow state transitions, etc., we have wrapped all Vaadin field components to facilitate automated binding to the business logic parts.

Now back to the original topic. All we had to do to facilitate an “automatic update” of UI components was to not use the setters of the entities/DTOs but the Bot-Attributes’ abstract interfaces for setting/retrieving values. They in turn can notify observers which update the UI components. Since all of the boiler plate code is generated by a code generator, the actual code to be written by the application developer is very lean, readable and with clearly separated concerns.

Well, I know that must sound pretty theoretical and complicated. Here is a very small example (taken from our internal Time Tracking Tool which I am currently re-implementing):

The fields “from”, “till”, “break” and “duration” can be entered manually. Changing one of the first three will automatically update the “duration” while manually entering the duration will re-calculate the “till” time.

All the UI developer has to do regarding those four fields is basically this:

The BL developer on the other hand does nothing but connect Bot-Attributes to Bot-Operations

… and implement the Bot-Operation:

All the rest, especially refreshing the “Duration” after manual input of start or end time happens automatically.

The best thing is, there is zero “presenter” code and therefore zero leaked BL knowledge in the UI. The BL on the other hand would not change a bit if invoked through a rest client or any other delivery mechanism.

The prize one has to pay for this, is following a strict approach of implementing business logic. Also, a code generator and a business logic runtime framework are essential if one does not want to implement a lot of infrastructure code.

If you are interested, I could maybe another time share more details how things like authorization, validation, required checks and so on are implemented based on the BOT concept.

3 years later – this is fascinating – Im working now on some related (at an abstract level) frameworks that have a similar need to model the coupling between business logic and implemenation. In my case only a small (and optional) bit of it relates to Vaadin – but the core concpets are similar – how to allow defining ‘workflows’ defined at different levels of abstraction or in different domains and ‘bind’ them – but only where appropreate.
This has given me some very good concepts to think about. Thank you !