Framework: Binder should automatically create intermediate objects if they are null

Created on 5 May 2017  路  6Comments  路  Source: vaadin/framework

public class Order {
    @OneToOne
    private Customer customer;
}
public class Customer {
    @NotNull
    @NotEmpty
    private String firstName;
}
protected TextField firstName = new TextField();

BeanValidationBinder<Order> binder = new BeanValidationBinder<>(Order.class);
binder.bind(firstName, "customer.firstName");
binder.setBean(new Order());

causes

java.lang.NullPointerException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.vaadin.data.BeanPropertySet.invokeWrapExceptions(BeanPropertySet.java:357)
    at com.vaadin.data.BeanPropertySet.access$1(BeanPropertySet.java:354)
    at com.vaadin.data.BeanPropertySet$NestedBeanPropertyDefinition.lambda$0(BeanPropertySet.java:219)
    at com.vaadin.data.Binder$BindingImpl.convertDataToFieldType(Binder.java:899)
    at com.vaadin.data.Binder$BindingImpl.initFieldValue(Binder.java:890)
    at com.vaadin.data.Binder$BindingImpl.access$0(Binder.java:885)
    at com.vaadin.data.Binder.lambda$1(Binder.java:1341)
    at java.lang.Iterable.forEach(Iterable.java:75)
    at com.vaadin.data.Binder.setBean(Binder.java:1341)

because the Customer bean is not created before trying to run its getter.

enhancement

Most helpful comment

Automatically creating a new instance would be a major improvement in most common cases, would cause quite easily understandable errors messages in most other cases (more easily understandable than the current NPE from Method.invoke) and might cause some hard-to-debug situations in a very limited number of cases. Sounds like the net result from a DX point of view would be overwhelmingly positive.

What would be required in order to reverse the design decision?

All 6 comments

It was an explicit design decision not to create intermediate objects because in the general case, it is not possible (no guarantee of suitable constructors, might want to have the objects managed by ORM/DI/..., might need additional parameters to create them correctly). Perhaps it is not documented clearly enough, though.

Isn't it based on beans?
JavaBeans are classes that encapsulate many objects into a single object (the bean). They are serializable, have a zero-argument constructor, and allow access to properties using getter and setter methods.

I think it would make sense to make it easy to use with beans and allow people with special needs to do their special things instead of forcing everybody to handle everything manually.

Automatically creating a new instance would be a major improvement in most common cases, would cause quite easily understandable errors messages in most other cases (more easily understandable than the current NPE from Method.invoke) and might cause some hard-to-debug situations in a very limited number of cases. Sounds like the net result from a DX point of view would be overwhelmingly positive.

What would be required in order to reverse the design decision?

I just ran into this weird looking NPE.

In my case I do not want to create the dependent object while the getter is being used: I just want the getter to return null in that case. I guess the framework can check on whether intermediate objects are null and just return null. When the setter is being used, only when the value to set is non-null, I would want the intermediate object to be created.

So:

  • please consider returning null while using the getter and an intermediate object is null
  • please consider creating the intermediate object when using the setter for a non-null value (for a null value, just return when the intermediate object is null)
  • even if the previous two are not considered, at least throw a meaningful error with a clear description when the intermediate object is null.

Hello there!

It looks like this issue hasn't progressed lately. There are so many issues that we just can't deal them all within a reasonable timeframe.

There are a couple of things you could help to get things rolling on this issue (this is an automated message, so expect that some of these are already in use):

  • Check if the issue is still valid for the latest version. There are dozens of duplicates in our issue tracker, so it is possible that the issue is already tackled. If it appears to be fixed, close the issue, otherwise report to the issue that it is still valid.
  • Provide more details how to reproduce the issue.
  • Explain why it is important to get this issue fixed and politely draw others attention to it e.g. via the forum or social media.
  • Add a reduced test case about the issue, so it is easier for somebody to start working on a solution.
  • Try fixing the issue yourself and create a pull request that contains the test case and/or a fix for it. Handling the pull requests is the top priority for the core team.
  • If the issue is clearly a bug, use the Warranty in your Vaadin subscription to raise its priority.

Thanks again for your contributions! Even though we haven't been able to get this issue fixed, we hope you to report your findings and enhancement ideas in the future too!

This needs to be re-verified with Vaadin 8.10 due https://github.com/vaadin/framework/pull/11758

Was this page helpful?
0 / 5 - 0 ratings

Related issues

vaadin-bot picture vaadin-bot  路  7Comments

FSchliephacke picture FSchliephacke  路  4Comments

vaadin-bot picture vaadin-bot  路  7Comments

SomeoneToIgnore picture SomeoneToIgnore  路  7Comments

edler-san picture edler-san  路  5Comments