-
Notifications
You must be signed in to change notification settings - Fork 169
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support Java records for form bindings #17947
Comments
It is possible to read data from Record with Binder, but naturally it is not supporting introspecting it using So one could envision to apply it for reactive views in some fashion like below.
The above trivial example makes it look quite clumsy though. I would like to use this example to provoke discussion about the actual use cases for Records with Binder. I feel that immutable Records are not the best fit for DTO's with two - way data transfer use case. |
I have been using Vaadin in a production environment for a while and I think that binding to records is most naturally a fit for CustomField implementations similar to the following.
In this case binding to record with validation can reduce a significant amount of boilerplate where currently you would need to have separate validation logic that executes in the generateModelValue and then extract the fields to construct the value object. The binder helps to centralize the object creation logic and makes it much more clear what the conditions are. The concept of using an immutable object to represent the value of a custom field already fits in nicely with many of the provided HasValue classes that come in vaadin-core. Like the DatePicker where you can set custom validation like min or max date or format. If any of these validation constraints are violated then the empty value is just returned instead and if it is valid the immutable value is returned so you don't have to worry about the value changing under you. This natural immutability is inherent in almost all of the basic provided HasValue classes and it would be great to easily provide this in user defined custom field classes As it currently stands to perform validation you need a mutable object. If you use this mutable object and just set it as the object for the binder then it is possible that after calling getValue on your custom field that the object could change as it proceeds through the backend if the user continues to interact with the widget and you have not taken the necessary precautions to prevent mutation. A record binder would greatly help to promote a better pattern of usage with immutability that naturally matches custom fields and can easily encourage best practices. One of the biggest challenges I for see is the actual binding syntax and enabling a form of type safety while limiting redundancy. In the example above I suggested a bind method of the form bind(Function<RECORD, VALUE> accessor, String componentName) so that you can achieve type safety while also providing the name of the component that can be used to reflectively construct the record. Granted it may be possible to use only the accessor and some deep magic with SerializedLambda's but I am not sure that can be assumed stable and reliable in the long run. |
Closing this as implementation was merged in #19806 |
Describe your motivation
Java records has been GA since Java 16. Since a record is immutable it is more suitable for a functional or 'data driven' coding style which Oracle is now more propagandising now there is better support for it in Java 21 (e.g. switch expressions).
Furthermore it greatly reduces the required code since it automatically provides getters, equals, toString, hashcode, etc.
Unfortunately Vaadin does not seem to support Java records yet.
There is this issue #16879 regarding support for serialising Java records.
Binding a record to form fields is also not supported yet since the binder looks for getter and setter methods in an object.
Describe the solution you'd like
Support Java records in a
Binder
where the Binder is able to provide a instance of the record with the contents of the bound fields when all fields are valid.Currently when using a Java Bean, a instance of the bean must be provided and the Binder can then write into the bean.
Since a Java record has no default constructor, it would be nicer if the binder could provide an instance of the record with all fields.
When creating a record, the binder should be smart enough to create an instance of a record for all bound form fields.
When reading a record, to fill the form, the binder should be smart enough to use the records property methods instead of the Java Bean getter methods.
Describe alternatives you've considered
Trying Java records with Vaadin 24.x throws an exception since it cannot find a getter method for a property.
Looking into the
Binder.java
sources it looked heavily tied to Java Bean and not easy to customise for records.Additional context
Java records are already supported in many frameworks like Spring, Hibernate, etc. It would be a pity if Vaadin would not support this Java language feature.
The text was updated successfully, but these errors were encountered: