Unsupported DataContext type:NoopDataContext

Hello,

In my application, no problem when an edit screen is opened from StandardLookup screen.

But if an edit screen is opened from a fragment embedded in StandardLookup, my application throws a “Unsupported DataContext type:NoopDataContext”.

The data of the fragment are linked to a property of an instance container in the master screen.

In all the cases, a StandardLookup has always a NoopDataContext. Nested container (data container linked via property) seems to cause the issue.

I don’t understand what’s happening …

Hi,
Please reproduce your problem on a small test project an attach it here.

Hi,

you can found not pretty project,

to reproduce :

  1. go to parents screen
    create parent with child
  2. go to pbs screen
    select parent created by double clicked on the grid
    under you can see instance of parent create with the child
    double click on child

noopdatacontext.zip (369.3 KB)

The problem occur when child have @composition
In this case StandardLookup > fragment > editor(call by ViewAction) DataContext will be required in setupParentDataContext
With StandardEditor it works

what is the best way to correct it?

best regards,

gabriel

java.lang.IllegalArgumentException: Unsupported DataContext type: com.haulmont.cuba.gui.model.impl.NoopDataContext
	at com.haulmont.cuba.gui.model.impl.DataContextImpl.setParent(DataContextImpl.java:112)
	at com.haulmont.cuba.gui.builders.EditorBuilderProcessor.setupParentDataContext(EditorBuilderProcessor.java:386)
	at com.haulmont.cuba.gui.builders.EditorBuilderProcessor.buildEditor(EditorBuilderProcessor.java:98)
	at com.haulmont.cuba.gui.builders.EditorBuilder.build(EditorBuilder.java:359)
	at com.haulmont.cuba.gui.actions.list.ViewAction.execute(ViewAction.java:291)
	at com.company.noopdatacontext.web.fragments.ChildrenFragment.lambda$onInit$0(ChildrenFragment.java:44)
	at com.haulmont.bali.events.EventHub.publish(EventHub.java:170)
	at com.haulmont.cuba.gui.components.actions.BaseAction.actionPerform(BaseAction.java:222)
	at com.haulmont.cuba.web.gui.components.WebAbstractDataGrid.handleDoubleClickAction(WebAbstractDataGrid.java:600)
	at com.haulmont.cuba.web.gui.components.WebAbstractDataGrid.onItemClick(WebAbstractDataGrid.java:375)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at com.vaadin.event.ListenerMethod.receiveEvent(ListenerMethod.java:496)
	at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:273)
	at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:237)
	at com.vaadin.server.AbstractClientConnector.fireEvent(AbstractClientConnector.java:1041)
	at com.vaadin.ui.Grid.access$500(Grid.java:145)
	at com.vaadin.ui.Grid$GridServerRpcImpl.itemClick(Grid.java:646)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:153)
	at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:115)
	at com.vaadin.server.communication.ServerRpcHandler.handleInvocation(ServerRpcHandler.java:431)
	at com.vaadin.server.communication.ServerRpcHandler.handleInvocations(ServerRpcHandler.java:396)
	at com.vaadin.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:260)
	at com.vaadin.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:82)
	at com.vaadin.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:40)
	at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1578)
	at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:425)
	at com.haulmont.cuba.web.sys.CubaApplicationServlet.serviceAppRequest(CubaApplicationServlet.java:329)
	at com.haulmont.cuba.web.sys.CubaApplicationServlet.service(CubaApplicationServlet.java:215)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:733)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:108)
	at org.springframework.web.filter.CompositeFilter.doFilter(CompositeFilter.java:74)
	at com.haulmont.cuba.web.sys.CubaHttpFilter.doFilter(CubaHttpFilter.java:93)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
	at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:690)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1590)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.base/java.lang.Thread.run(Thread.java:834)

Hi Gabriel,

Thanks for the test project.

@Composition means that the child entity is saved only together with the parent. So when the standard Parent browser -> Parent editor -> Child editor screen flow is used, child instances are saved by the Parent editor.

In your sample project you have Parent browser/editor -> Child editor screen flow. So probably your Parent browser/editor should save changed Parent and Child entities. Then just remove readOnly="true" from the Parent browser/editor screen and add an action to save changes: dataContext.commit().

Regards,
Konstantin

thanks Konstantin for you’re fast anwser,

*) remove @compostion solved but it’s a good helper in some case
Parentcontext
*) trun false readyonly work too. is it secure? in this case we have noopdataContext we flow by StandardLookup

I just surprise. I don’t understand why ? in this specifics case, call an editor by viewAction for only view require this . I understand Composition require some control for editing

EditorBuilderProcessor

protected DataContext setupParentDataContext(FrameOwner origin, Screen screen, InstanceContainer container,
                                             @Nullable DataContext parentContext) {
    DataContext dataContext = parentContext;
    if (dataContext == null && container instanceof Nested) {
        InstanceContainer masterContainer = ((Nested) container).getMaster();
        String property = ((Nested) container).getProperty();

        MetaClass masterMetaClass = masterContainer.getEntityMetaClass();
        MetaProperty metaProperty = masterMetaClass.getPropertyNN(property);

        if (metaProperty.getType() == MetaProperty.Type.COMPOSITION) {
            dataContext = UiControllerUtils.getScreenData(origin).getDataContext();
        }
    }
    if (dataContext != null) {
        DataContext childContext = UiControllerUtils.getScreenData(screen).getDataContext();
        checkDataContext(screen, childContext);
        childContext.setParent(dataContext);
    }
    return dataContext;
}

regards,

gabriel