Hi
For years I’m using Cuba I always struggled with the “unfetched attribute” issue that I have seen a milion times, here is another one
Sample project attached, featuring some “patterns”:
- entity with calculated fields that can traverse relationships graph (
CarTransaction
) - entity that knows how to recalculate itself even by using an external class for that (
CarTransactionCalculator
) - through recomputing entity can create or modify child objects (
CarDocument
) - entity to be recomputed and updated in UI when a dependent field/relationship is changed
- simple calculated fields calculated on the fly and bound in UI components (hence
@MetaProperty
) - simple calculated field as MetaProperties to be updated in UI when entity changes (
CalculatedEditorScreen.updateFieldsBoundToReadOnlyProperties
)
This control flow is not straightforward in Cuba and project attached tries to adapt. Issue can be reproduced by creating a CarTransaction
adding 1 payment, save, reload, modify, save.
Caused by: org.eclipse.persistence.exceptions.ValidationException:
Exception Description: An attempt was made to traverse a relationship using indirection that had a null Session. This often occurs when an entity with an uninstantiated LAZY relationship is serialized and that relationship is traversed after serialization. To avoid this issue, instantiate the LAZY relationship prior to serialization.
at org.eclipse.persistence.exceptions.ValidationException.instantiatingValueholderWithNullSession(ValidationException.java:1026) ~[org.eclipse.persistence.core-2.7.3-6-cuba.jar:na]
at org.eclipse.persistence.internal.indirection.UnitOfWorkValueHolder.instantiate(UnitOfWorkValueHolder.java:235) ~[org.eclipse.persistence.core-2.7.3-6-cuba.jar:na]
at org.eclipse.persistence.internal.indirection.DatabaseValueHolder.getValue(DatabaseValueHolder.java:107) ~[org.eclipse.persistence.core-2.7.3-6-cuba.jar:na]
at com.company.testcuba72.entity.Payment._persistence_get_counterpart(Payment.java) ~[test-global-0.1-SNAPSHOT.jar:na]
at com.company.testcuba72.entity.Payment.getCounterpart(Payment.java:70) ~[test-global-0.1-SNAPSHOT.jar:na]
at com.company.testcuba72.entity.CarTransaction.lambda$getSellerRefunds$0(CarTransaction.java:127) ~[test-global-0.1-SNAPSHOT.jar:na]
at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:174) ~[na:1.8.0_172]
at java.util.Vector$VectorSpliterator.forEachRemaining(Vector.java:1440) ~[na:1.8.0_172]
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) ~[na:1.8.0_172]
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) ~[na:1.8.0_172]
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) ~[na:1.8.0_172]
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:1.8.0_172]
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499) ~[na:1.8.0_172]
at com.company.testcuba72.entity.CarTransaction.getSellerRefunds(CarTransaction.java:127) ~[test-global-0.1-SNAPSHOT.jar:na]
at com.company.testcuba72.entity.CarTransaction.getTotalSellerRefunds(CarTransaction.java:133) ~[test-global-0.1-SNAPSHOT.jar:na]
at com.haulmont.chile.core.model.impl.AbstractInstance.getValue(AbstractInstance.java:108) ~[cuba-global-7.2.0.jar:7.2.0]
at com.haulmont.cuba.core.entity.BaseGenericIdEntity.getValue(BaseGenericIdEntity.java:146) ~[cuba-global-7.2.0.jar:7.2.0]
at com.haulmont.cuba.gui.model.impl.DataContextImpl.mergeState(DataContextImpl.java:249) ~[cuba-gui-7.2.0.jar:7.2.0]
at com.haulmont.cuba.gui.model.impl.DataContextImpl.internalMerge(DataContextImpl.java:214) ~[cuba-gui-7.2.0.jar:7.2.0]
at com.haulmont.cuba.gui.model.impl.DataContextImpl.mergeState(DataContextImpl.java:290) ~[cuba-gui-7.2.0.jar:7.2.0]
at com.haulmont.cuba.gui.model.impl.DataContextImpl.internalMerge(DataContextImpl.java:214) ~[cuba-gui-7.2.0.jar:7.2.0]
at com.haulmont.cuba.gui.model.impl.DataContextImpl.merge(DataContextImpl.java:172) ~[cuba-gui-7.2.0.jar:7.2.0]
at com.haulmont.cuba.gui.model.impl.DataContextImpl.mergeCommitted(DataContextImpl.java:715) ~[cuba-gui-7.2.0.jar:7.2.0]
at com.haulmont.cuba.gui.model.impl.DataContextImpl.commit(DataContextImpl.java:607) ~[cuba-gui-7.2.0.jar:7.2.0]
at com.haulmont.cuba.gui.screen.StandardEditor.lambda$commitChanges$4(StandardEditor.java:423) ~[cuba-gui-7.2.0.jar:7.2.0]
at com.haulmont.cuba.gui.screen.StandardEditor.commitChanges(StandardEditor.java:438) ~[cuba-gui-7.2.0.jar:7.2.0]
at com.haulmont.cuba.gui.screen.StandardEditor.closeWithCommit(StandardEditor.java:587) ~[cuba-gui-7.2.0.jar:7.2.0]
at com.haulmont.cuba.gui.screen.StandardEditor.commitAndClose(StandardEditor.java:553) ~[cuba-gui-7.2.0.jar:7.2.0]
at com.haulmont.bali.events.EventHub.publish(EventHub.java:170) ~[cuba-global-7.2.0.jar:7.2.0]
at com.haulmont.cuba.gui.components.actions.BaseAction.actionPerform(BaseAction.java:224) ~[cuba-gui-7.2.0.jar:7.2.0]
at com.haulmont.cuba.web.gui.components.WebButton.buttonClicked(WebButton.java:67) ~[cuba-web-7.2.0.jar:7.2.0]
at com.haulmont.cuba.web.widgets.CubaButton.fireClick(CubaButton.java:76) ~[cuba-web-widgets-7.2.0.jar:na]
at com.vaadin.ui.Button$1.click(Button.java:57) ~[vaadin-server-8.9.2-3-cuba.jar:8.9.2-3-cuba]
... 42 common frames omitted
While counterpart
field of Payment
is actually included in the view of editor.
<view entity="testcuba72_CarTransaction" name="carTransaction-view" extends="_local">
<property name="buyer" view="_local"/>
<property name="seller" view="_local"/>
<property name="expenses" view="_local"/>
<property name="services" view="_local"/>
<property name="documents" view="_local"/>
<property name="payments" view="_local">
<property name="counterpart" view="_minimal"/>
</property>
</view>
I do not understand how DataContext merge
gets a Payment
instance with no counterpart.
Regards
Michael
testcuba72.zip (109.0 KB)