KeyValueContainer and return from edit screen

Hi,

I’ve created a screen with KeyValueContainer:

  • no JPQL query defined in DL
  • load delegate on DL with JPQL query
  • screen class defined for specifying edit screen

Values are properly loaded in table at opening or refreshed.

Edit screen instance deserialization throws an exception. Application seems to try to use a getter for a property defined in KeyValueContainer but missing in edited instance type.

Best regards, Stef.

Stack trace:

java.lang.IllegalArgumentException: Can’t find getter for property ‘score’ at class com.cooperl.si.mdm.entity.tiers.sv.SVPersonneMorale
at com.haulmont.chile.core.model.utils.MethodsCache.getGetterNN(MethodsCache.java:155) ~[cuba-global-7.2.5.jar:7.2.5]
at com.haulmont.chile.core.model.impl.AbstractInstance.getValue(AbstractInstance.java:107) ~[cuba-global-7.2.5.jar:7.2.5]
at com.haulmont.cuba.core.entity.BaseGenericIdEntity.getValue(BaseGenericIdEntity.java:146) ~[cuba-global-7.2.5.jar:7.2.5]
at com.haulmont.chile.core.model.utils.InstanceUtils.getValueEx(InstanceUtils.java:134) ~[cuba-global-7.2.5.jar:7.2.5]
at com.haulmont.chile.core.model.impl.AbstractInstance.getValueEx(AbstractInstance.java:172) ~[cuba-global-7.2.5.jar:7.2.5]
at com.haulmont.cuba.web.gui.components.valueproviders.EntityValueProvider.apply(EntityValueProvider.java:38) ~[cuba-web-7.2.5.jar:7.2.5]
at com.haulmont.cuba.web.gui.components.valueproviders.EntityValueProvider.apply(EntityValueProvider.java:23) ~[cuba-web-7.2.5.jar:7.2.5]
at com.vaadin.ui.Grid$Column.generateRendererValue(Grid.java:1111) ~[vaadin-server-8.9.2-10-cuba.jar:8.9.2-10-cuba]
at com.vaadin.ui.Grid$Column.access$1100(Grid.java:849) ~[vaadin-server-8.9.2-10-cuba.jar:8.9.2-10-cuba]
at com.vaadin.ui.Grid$Column$1.generateData(Grid.java:898) ~[vaadin-server-8.9.2-10-cuba.jar:8.9.2-10-cuba]
at com.vaadin.data.provider.DataCommunicator.getDataObject(DataCommunicator.java:485) ~[vaadin-server-8.9.2-10-cuba.jar:8.9.2-10-cuba]
at com.vaadin.data.provider.DataCommunicator.pushData(DataCommunicator.java:465) ~[vaadin-server-8.9.2-10-cuba.jar:8.9.2-10-cuba]
at com.vaadin.data.provider.DataCommunicator.sendDataToClient(DataCommunicator.java:387) ~[vaadin-server-8.9.2-10-cuba.jar:8.9.2-10-cuba]
at com.vaadin.data.provider.DataCommunicator.beforeClientResponse(DataCommunicator.java:343) ~[vaadin-server-8.9.2-10-cuba.jar:8.9.2-10-cuba]
at com.vaadin.server.communication.UidlWriter.write(UidlWriter.java:118) ~[vaadin-server-8.9.2-10-cuba.jar:8.9.2-10-cuba]
at com.vaadin.server.communication.UidlRequestHandler.writeUidl(UidlRequestHandler.java:115) ~[vaadin-server-8.9.2-10-cuba.jar:8.9.2-10-cuba]
at com.vaadin.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:84) ~[vaadin-server-8.9.2-10-cuba.jar:8.9.2-10-cuba]
at com.vaadin.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:40) ~[vaadin-server-8.9.2-10-cuba.jar:8.9.2-10-cuba]
at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1578) ~[vaadin-server-8.9.2-10-cuba.jar:8.9.2-10-cuba]
at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:425) ~[vaadin-server-8.9.2-10-cuba.jar:8.9.2-10-cuba]
at com.haulmont.cuba.web.sys.CubaApplicationServlet.serviceAppRequest(CubaApplicationServlet.java:329) ~[cuba-web-7.2.5.jar:7.2.5]
at com.haulmont.cuba.web.sys.CubaApplicationServlet.service(CubaApplicationServlet.java:215) ~[cuba-web-7.2.5.jar:7.2.5]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) ~[servlet-api.jar:na]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[catalina.jar:9.0.27]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[catalina.jar:9.0.27]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-websocket.jar:9.0.27]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[catalina.jar:9.0.27]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[catalina.jar:9.0.27]
at org.springframework.web.filter.CompositeFilter$VirtualFilterChain.doFilter(CompositeFilter.java:108) ~[spring-web-5.2.3.RELEASE.jar:5.2.3.RELEASE]
at org.springframework.web.filter.CompositeFilter.doFilter(CompositeFilter.java:74) ~[spring-web-5.2.3.RELEASE.jar:5.2.3.RELEASE]
at com.haulmont.cuba.web.sys.CubaHttpFilter.doFilter(CubaHttpFilter.java:93) ~[cuba-web-7.2.5.jar:7.2.5]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[catalina.jar:9.0.27]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[catalina.jar:9.0.27]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) ~[catalina.jar:9.0.27]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) ~[catalina.jar:9.0.27]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:526) ~[catalina.jar:9.0.27]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) ~[catalina.jar:9.0.27]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) ~[catalina.jar:9.0.27]
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:678) ~[catalina.jar:9.0.27]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[catalina.jar:9.0.27]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) ~[catalina.jar:9.0.27]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408) ~[tomcat-coyote.jar:9.0.27]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) ~[tomcat-coyote.jar:9.0.27]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861) ~[tomcat-coyote.jar:9.0.27]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1579) ~[tomcat-coyote.jar:9.0.27]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-coyote.jar:9.0.27]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-util.jar:9.0.27]
at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]

master screen: add-filter-exception.zip (5.1 KB)
edit screen: return-from-edit-screen-exception.zip (7.1 KB)

Hi Stef,

The exception occurs because the standard edit action tries to set the edited entity back to the collection container of the table, but the edited entity is of another type.

You should override the action’s behavior and use ScreenBuilders.editor() method directly without passing the collection container to it and just reload your collection after the editor commit. See an example below.

I’ve tested it on this project: demo.zip (82.4 KB)

@Inject
private KeyValueCollectionContainer customersDc;
@Inject
private KeyValueCollectionLoader customersDl;
@Inject
private ScreenBuilders screenBuilders;
@Inject
private DataManager dataManager;

@Subscribe("customersTable.edit")
public void onCustomersTableEdit(Action.ActionPerformedEvent event) {
    screenBuilders.editor(Customer.class, this)
            .withScreenClass(CustomerEdit.class)
            .editEntity(dataManager.load(Customer.class).id((UUID) customersDc.getItem().getId()).one())
            .withAfterCloseListener(afterCloseEvent -> {
                if (afterCloseEvent.closedWith(StandardOutcome.COMMIT)) {
                    customersDl.load();
                }
            })
            .show();
}

That’s it, thank you !