Java Records with Binder ReadOnly Mode not possible

I am using Binder with a Java Record but the binder.setReadOnly(true) is ignored:

  private final Binder<MyJavaRecord> binder = new Binder<>(MyJavaRecord.class);
  private final TextField timestamp = new TextField("timestamp");
…
  binder.bindInstanceFields(this);

  // timestamp.setReadOnly(true); // THIS DOES WORK
  binder.setReadOnly(true); // THIS DOES NOT WORK
…
  binder.readBean(myJavaRecord);

The text field is still writeable. Setting readOnly on the individual textField works.

1 Like

Oh wow, I didn’t even know you could set a binder to be read only. But it occurs to me, aren’t records effectively read only already?

Looking at the source code the binder checks for a setter but records do not have setters.
IMO this is a bug. Please create a bug report on GitHub

1 Like

I think it is by design.
Records do not have setters as Simon said, so to support them with binder Flow cannot set the field as read only, otherwise the fields will be never editable.

If you need to make the record field read only, you have to bind it manually.
Or you can modify the binding if you used bindInstanceFields

binder.getBinding("timestamp").ifPresent(b -> b.setReadOnly(true));

IMO having Records in a Binder with data binding is conceptually wrong. But that’s off topic :sweat_smile:

3 Likes

I understand your point of view and I can agree :wink:
But many other people were asking for record support in Binder

I’m the outlier. I use records for all DTO objects and for everything else where I can get away with it. As soon as the binder started to support records, I changed all of my projects over to use it. I appreciate it! :)

I don’t use DTOs for mutable data. As a jOOQ user I directly bind the UpdatableRecords that will automatically generate minimal updates.

Records are for immutable data and I use it for Grids and other read only components

Setting the binder to readOnly, will make the bounded TextFields readonly and not the record itself. The record is immutable and that is the reason why writeBean has to be used as stated out in the documentation.

I don’t see a conceptual difference of using a JavaBean or a Record for readOnly data to be presented to the user and having all Components therefore set readonly.

Java Records might be used to transport data to the UI and only show it to users. The Binder is still very handy for this use case. The concept of the binder allows readonly mode as well and therefore, Records fit in this concept perfectly for special use cases.

In my case, we use Java Records heavily to map JSON onto it. This way the model is very concise and is just a 1:1 representation of the JSON. If only showing this data to the user, Java Record and Binder is a valid use case.

I will raise a bug ticket as the binder should behave the same for JavaBeans and Records in readonly mode.

1 Like

You mean that when working with records, you expect fields always to be read only?

Absolutely not. When working with records and Binder, you need to use readBean and writeBean instead of the getter/setter methods of a JavaBean. (And now I am with @SimonMartinelli - When using mutable objects, I would use JavaBean and use the getter/setter of that object).

What I say is, if you want to use Binder in readOnly mode, then I don’t see a conceptual difference of using JavaBean or Java Records as data container. In either case, setting binder.setReadOnly(true) should disable writing of Components like TextField. No matter if the Binder is bound to a Record or a JavaBean.

Now I see.
The issue is not with record support as is, but in Binder.setReadonly() not working properly with records.
This is a bug indeed

Thanks.

2 Likes

@marcoc_753 Ah! You already fixed it. Nice! ;-) Medal for super fast action…

2 Likes