New Grid component throwing ConversionException

I am trying out the new Grid component in my Application, replacing the Table component. So far it is quite easy to migrate (great job!). However, when using the Grid component with an existing (and working custom Indexed Container) i get:

com.vaadin.data.util.converter.Converter$ConversionException: Unable to convert value of type java.lang.Integer to presentation type java.lang.String. No converter is set and the types are not compatible. This is just a “normal” integer column for which a default Converter is present in Vaadin. Is this a know problem? Or is this intended? So what is the best approach?

Hi Ronald,

Could you copypaste the whole stack trace, including any “cause” exceptions? Plus a test case would be nice if you can reduce your application into one. An integer column should “just work” so this is either a bug or perhaps some issue in your code.

Stacktrace is:

12:12:06.030 |ERROR| Unable to convert value of type java.lang.Integer to presentation type java.lang.String. No converter is set and the types are not compatible. | com.vaadin.data.RpcDataProviderExtension >>>>>> com.vaadin.data.util.converter.Converter$ConversionException: Unable to convert value of type java.lang.Integer to presentation type java.lang.String. No converter is set and the types are not compatible. com.vaadin.data.RpcDataProviderExtension.encodeValue(RpcDataProviderExtension.java:979) com.vaadin.data.RpcDataProviderExtension.getRowData(RpcDataProviderExtension.java:751) com.vaadin.data.RpcDataProviderExtension.pushRowData(RpcDataProviderExtension.java:733) com.vaadin.data.RpcDataProviderExtension.access$900(RpcDataProviderExtension.java:74) com.vaadin.data.RpcDataProviderExtension$2.requestRows(RpcDataProviderExtension.java:672) sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) java.lang.reflect.Method.invoke(Method.java:483) com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:168) com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:118) com.vaadin.server.communication.ServerRpcHandler.handleInvocations(ServerRpcHandler.java:290) com.vaadin.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:183) com.vaadin.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:92) com.vaadin.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:41) com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1408) com.vaadin.server.VaadinServlet.service(VaadinServlet.java:305) javax.servlet.http.HttpServlet.service(HttpServlet.java:790) org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:800) org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:587) org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:577) org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:223) org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1125) org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515) org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185) org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1059) org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:215) org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:110) org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) org.eclipse.jetty.server.Server.handle(Server.java:497) org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:310) org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:248) org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:540) org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:620) org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:540) java.lang.Thread.run(Thread.java:745) Creating a test case wil take some more time … :slight_smile: I do not know if that is feasable, because the code is quite large. Howver it worked with a Table component and will come back with some details.

Hmm, strange.

It seems that exception should only occur if the converter for that column is explicitly set to null - otherwise, when the column is created, it should find a suitable converter from the column type to String. And indeed, in our test case it does find StringToIntegerConverter without problems.

I found it (i assume). We use a property type “Object” for a column (table shows key/value pairs where the key title is always a String and the value type differs from row to row), so Property#getType() returns Object.class. However the actual type in the reported case is an Integer. This use case is handled by the Table component, but not by the Grid component, which is more strict.

Ah, all right! I knew this sounded familiar but couldn’t find the ticket. This is stricter than Table semi-by-design; I think Table just falls back to Object.toString if there’s no converter set. However, the exception message is indeed not very helpful, and there’s a recent ticket about adding a
StringToObjectConverter
for this use case. Or we could maybe add a toString fallback to Grid too; in fact, the client-side Grid already has one.

Thanks for your fast and very helpful comments!

IMHO Vaadin should strive for making the behaviour as similar as possible. For many users the Grid will be used as a more flexible, powerful and performant drop-in replacement for the Table component.
In this case i would suggest for the same fallback scenario as Table uses.