Skip to content

Implement serialization of KeyValueEntity without using MetaClass #104

@belyaev-andrey

Description

@belyaev-andrey

Environment

  • Platform version: 7.x
  • Addon version: 7.2.0

Description of the bug or enhancement

When a published service returns a KeyValue entity, its serialization to JSON fails because the metadata is null.
We do not add metadata when returning entities from datastore, but add it in the UI when adding KVEntity to the container:

com.haulmont.cuba.gui.model.impl.KeyValueCollectionContainerImpl#updateEntityMetadata

During serialization we invoke

com.haulmont.cuba.core.global.MetadataTools#isEmbeddable(com.haulmont.chile.core.model.MetaClass) 

And got NPE.

See https://www.cuba-platform.com/discuss/t/exception-in-rest-controller/12424

Run the application add a Customer and then try to invoke a published service using http://localhost:8080/app/rest/v2/services/restapithouthgs_RestService/getBuyer URL

  • Expected behavior
    Entity should be returned

  • Actual behavior

22:06:21.009 ERROR c.h.a.r.a.c.RestControllerExceptionHandler- Exception in REST controller
java.lang.IllegalStateException: metaClass is null
	at com.haulmont.cuba.core.entity.KeyValueEntity.getMetaClass(KeyValueEntity.java:71) ~[cuba-global-7.2.4.jar:7.2.4]
	at com.haulmont.cuba.core.app.serialization.EntitySerialization$EntitySerializer.serializeEntity(EntitySerialization.java:217) ~[cuba-global-7.2.4.jar:7.2.4]
	at com.haulmont.cuba.core.app.serialization.EntitySerialization$EntitySerializer.serialize(EntitySerialization.java:212) ~[cuba-global-7.2.4.jar:7.2.4]
	at com.haulmont.cuba.core.app.serialization.EntitySerialization$EntitySerializer.serialize(EntitySerialization.java:189) ~[cuba-global-7.2.4.jar:7.2.4]
	at com.google.gson.internal.bind.TreeTypeAdapter.write(TreeTypeAdapter.java:81) ~[gson-2.8.6.jar:na]
	at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:69) ~[gson-2.8.6.jar:na]
	at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:97) ~[gson-2.8.6.jar:na]
	at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.write(CollectionTypeAdapterFactory.java:61) ~[gson-2.8.6.jar:na]
	at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:69) ~[gson-2.8.6.jar:na]
	at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.write(MapTypeAdapterFactory.java:208) ~[gson-2.8.6.jar:na]
	at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.write(MapTypeAdapterFactory.java:145) ~[gson-2.8.6.jar:na]
	at com.google.gson.Gson.toJson(Gson.java:704) ~[gson-2.8.6.jar:na]
	at com.google.gson.Gson.toJson(Gson.java:683) ~[gson-2.8.6.jar:na]
	at com.google.gson.Gson.toJson(Gson.java:638) ~[gson-2.8.6.jar:na]
	at com.google.gson.Gson.toJson(Gson.java:618) ~[gson-2.8.6.jar:na]
	at com.haulmont.cuba.core.app.serialization.EntitySerialization.objectToJson(EntitySerialization.java:115) ~[cuba-global-7.2.4.jar:7.2.4]
	at com.haulmont.addon.restapi.api.common.RestParseUtils.serialize(RestParseUtils.java:126) ~[restapi-rest-api-7.2.0.jar:na]
	at com.haulmont.addon.restapi.api.service.ServicesControllerManager._invokeServiceMethod(ServicesControllerManager.java:189) ~[restapi-rest-api-7.2.0.jar:na]
	at com.haulmont.addon.restapi.api.service.ServicesControllerManager.invokeServiceMethodGet(ServicesControllerManager.java:83) ~[restapi-rest-api-7.2.0.jar:na]
	at com.haulmont.addon.restapi.api.controllers.ServicesController.invokeServiceMethodGet(ServicesController.java:62) ~[restapi-rest-api-7.2.0.jar:na]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_172]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_172]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_172]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_172]
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190) ~[spring-web-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106) ~[spring-webmvc-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:888) ~[spring-webmvc-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:793) ~[spring-webmvc-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1040) ~[spring-webmvc-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943) ~[spring-webmvc-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) [spring-webmvc-5.2.3.RELEASE.jar:5.2.3.RELEASE]
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) [spring-webmvc-5.2.3.RELEASE.jar:5.2.3.RELEASE]

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions