Inconsistent null handling in ComponentDataGenerator
Description
There is an inconsistency in the handling of null values in the ComponentDataGenerator which can cause unexpected NullPointerExceptions.
In the method createComponent a null is handled gracefully and an empty Text is used as content. But if the grid is refreshed and the components are re-rendered, the refreshData method in AbstractComponentDataGenerator calls updateComponent which does not perform this null handling, and it inevitably encounters a null pointer.
Expected outcome
The null values returned by ComponentRenderers should be accepted in both cases - when creating the cell and when updating the cell content.
Steps to reproduce
1.) Create a grid with component renderer which returns null as value. 2.) Call DataProvider#refreshItem on any row
Environment
Vaadin version(s): 24.5.4
Browsers
No response
We encountered the same issue with Vaadin Version 24.5.4
Any progress here?
Same issue still in 24.6.4
We have this issue too, here is a callstack:
at com.vaadin.flow.data.provider.AbstractComponentDataGenerator.refreshData(AbstractComponentDataGenerator.java:52) ~[flow-data-24.5.4.jar:24.5.4]
at com.vaadin.flow.data.provider.CompositeDataGenerator.lambda$refreshData$2(CompositeDataGenerator.java:62) ~[flow-data-24.5.4.jar:24.5.4]
at java.base/java.lang.Iterable.forEach(Iterable.java:75) ~[?:?]
at com.vaadin.flow.data.provider.CompositeDataGenerator.refreshData(CompositeDataGenerator.java:62) ~[flow-data-24.5.4.jar:24.5.4] at com.vaadin.flow.data.provider.CompositeDataGenerator.lambda$refreshData$2(CompositeDataGenerator.java:62) ~[flow-data-24.5.4.jar:24.5.4]
at java.base/java.lang.Iterable.forEach(Iterable.java:75) ~[?:?]
at com.vaadin.flow.data.provider.CompositeDataGenerator.refreshData(CompositeDataGenerator.java:62) ~[flow-data-24.5.4.jar:24.5.4]
at com.vaadin.flow.data.provider.DataCommunicator.refresh(DataCommunicator.java:405) ~[flow-data-24.5.4.jar:24.5.4]
at com.vaadin.flow.data.provider.DataCommunicator.handleDataRefreshEvent(DataCommunicator.java:1108) ~[flow-data-24.5.4.jar:24.5.4]
at com.vaadin.flow.data.provider.hierarchy.HierarchicalDataCommunicator.handleDataRefreshEvent(HierarchicalDataCommunicator.java:178) ~[flow-data-24.5.4.jar:24.5.4] at com.vaadin.flow.data.provider.DataCommunicator.lambda$handleAttach$425c8a01$1(DataCommunicator.java:1097) ~[flow-data-24.5.4.jar:24.5.4]
at com.vaadin.flow.data.provider.AbstractDataProvider$1.accept(AbstractDataProvider.java:64) ~[flow-data-24.5.4.jar:24.5.4]
at com.vaadin.flow.data.provider.AbstractDataProvider$1.accept(AbstractDataProvider.java:61) ~[flow-data-24.5.4.jar:24.5.4]
at com.vaadin.flow.data.provider.AbstractDataProvider.fireEventForListener(AbstractDataProvider.java:147) ~[flow-data-24.5.4.jar:24.5.4]
at com.vaadin.flow.data.provider.AbstractDataProvider.lambda$fireEvent$2(AbstractDataProvider.java:133) ~[flow-data-24.5.4.jar:24.5.4]
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596) ~[?:?]
at com.vaadin.flow.data.provider.AbstractDataProvider.lambda$fireEvent$3(AbstractDataProvider.java:132) ~[flow-data-24.5.4.jar:24.5.4]
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184) ~[?:?]
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179) ~[?:?]
at java.base/java.util.HashMap$EntrySpliterator.forEachRemaining(HashMap.java:1858) ~[?:?]
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509) ~[?:?]
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) ~[?:?]
at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151) ~[?:?]
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174) ~[?:?]
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[?:?]
at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596) ~[?:?]
at com.vaadin.flow.data.provider.AbstractDataProvider.fireEvent(AbstractDataProvider.java:132) ~[flow-data-24.5.4.jar:24.5.4]
at com.vaadin.flow.data.provider.AbstractDataProvider.refreshItem(AbstractDataProvider.java:82) ~[flow-data-24.5.4.jar:24.5.4]
at de.economed.webapp.view.api.AnyDataProvider.updateItem(AnyDataProvider.java:303) ~[classes/:?]
at de.economed.webapp.view.kategorien.KategorienAssignPanel.assign(KategorienAssignPanel.java:199) ~[classes/:?]
at de.economed.webapp.view.api.AbstractAssignGridPanel$1.assign(AbstractAssignGridPanel.java:109) ~[classes/:?]```
No progress here, no workaround suggested... ? You are all busy preparing for the next Vaadin conference...?
Thanks for your message! Just to clarify, events like conferences don't affect how we handle maintenance or issue prioritisation. The team continues working on fixes and improvements in parallel, following the same structured process as always.
We're a relatively small team maintaining a large framework with thousands of open items, so we focus on the issues with the greatest impact first. Some valid reports can take longer to reach implementation simply because of that balance.
We're aiming to improve transparency and communication around priorities, and we appreciate everyone's understanding and patience as we work through the backlog.
This case remains on our radar and will be handled as part of our ongoing maintenance work once it reaches its turn in the queue.
As a possible workaround, the component renderer could return an empty text (new Text("")) instead of null.
Sorry, if I was a bit harsh here, but the issue exists round about one year now... without any progress or comment. We are using already such a workaround, but still waiting for a better solution directly by the framework itself - null handling seems to me like butter and bread in java...
This ticket/PR has been released with Vaadin 24.8.12.
This ticket/PR has been released with Vaadin 24.9.4.