TreeGrid and EditorComponent, java.lang.IllegalStateException: Duplicate ke

I’m not sure if i’m doing something wrong. In my TreeGrid i want to enable editing the root elements with a simple TextField.
I’ve added a EditorComponent to one column and a method which is called after saving the value. Although the sample code is not pure java, it’s hopefully understandable:

treeGrid.addColumn([s | s.name] ) .setCaption("name") .setId("NAME") .setEditorComponent(new TextField(), [ MyBean s, String b | s.name = b; /* some more code */] ) .editable = true In the commented code place /* some more code */ i have played with

treeGrid.dataProvider.refreshItem(s) treeGrid.dataProvider.refreshAll in every combination - but without success.

To explain what’s happening i’ve attached some screenshots.
Image 1: The intial tree
Image 2: Double-Click on “Root 1”. The TextField is shown and i changed the string value and click save.
Image 3: The root element was renamed, but lost all children

And after this, i tried to expand/collapse “Root 2” and got the exception. Which duplicate key?

java.lang.IllegalStateException: Duplicate key MyBean [ name = "Root 1 New" ] at java.util.stream.Collectors.lambda$throwingMerger$113(Collectors.java:133) at java.util.stream.Collectors$$Lambda$111/29693021.apply(Unknown Source) at java.util.HashMap.merge(HashMap.java:1245) at java.util.stream.Collectors.lambda$toMap$171(Collectors.java:1320) at java.util.stream.Collectors$$Lambda$113/14412336.accept(Unknown Source) at java.util.stream.ReduceOps$3ReducingSink.accept(ReduceOps.java:169) at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) at java.util.HashMap$KeySpliterator.forEachRemaining(HashMap.java:1540) at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:512) at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:502) at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499) at com.vaadin.data.provider.DataCommunicator$ActiveDataHandler.getActiveData(DataCommunicator.java:165) at com.vaadin.data.provider.DataCommunicator.refresh(DataCommunicator.java:521) at com.vaadin.data.provider.HierarchicalDataCommunicator.doCollapse(HierarchicalDataCommunicator.java:178) at com.vaadin.ui.TreeGrid$1.setNodeCollapsed(TreeGrid.java:130) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:155) at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:116) at com.vaadin.server.communication.ServerRpcHandler.handleInvocation(ServerRpcHandler.java:445) at com.vaadin.server.communication.ServerRpcHandler.handleInvocations(ServerRpcHandler.java:410) at com.vaadin.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:274) at com.vaadin.server.communication.PushHandler.lambda$new$1(PushHandler.java:145) at com.vaadin.server.communication.PushHandler$$Lambda$13/20793996.run(Unknown Source) at com.vaadin.server.communication.PushHandler.callWithUi(PushHandler.java:235) at com.vaadin.server.communication.PushHandler.onMessage(PushHandler.java:520) at com.vaadin.server.communication.PushAtmosphereHandler.onMessage(PushAtmosphereHandler.java:87) at com.vaadin.server.communication.PushAtmosphereHandler.onRequest(PushAtmosphereHandler.java:77) at org.atmosphere.cpr.AsynchronousProcessor.action(AsynchronousProcessor.java:223) at org.atmosphere.cpr.AsynchronousProcessor.suspended(AsynchronousProcessor.java:115) at org.atmosphere.container.Servlet30CometSupport.service(Servlet30CometSupport.java:67) at org.atmosphere.cpr.AtmosphereFramework.doCometSupport(AtmosphereFramework.java:2284) at org.atmosphere.websocket.DefaultWebSocketProcessor.dispatch(DefaultWebSocketProcessor.java:593) at org.atmosphere.websocket.DefaultWebSocketProcessor$3.run(DefaultWebSocketProcessor.java:345) at org.atmosphere.util.VoidExecutorService.execute(VoidExecutorService.java:101) at org.atmosphere.websocket.DefaultWebSocketProcessor.dispatch(DefaultWebSocketProcessor.java:340) at org.atmosphere.websocket.DefaultWebSocketProcessor.invokeWebSocketProtocol(DefaultWebSocketProcessor.java:447) at org.atmosphere.container.JSR356Endpoint$3.onMessage(JSR356Endpoint.java:272) at org.atmosphere.container.JSR356Endpoint$3.onMessage(JSR356Endpoint.java:269) at org.eclipse.jetty.websocket.jsr356.messages.TextWholeMessage.messageComplete(TextWholeMessage.java:56) at org.eclipse.jetty.websocket.jsr356.endpoints.JsrEndpointEventDriver.onTextFrame(JsrEndpointEventDriver.java:218) at org.eclipse.jetty.websocket.common.events.AbstractEventDriver.incomingFrame(AbstractEventDriver.java:162) at org.eclipse.jetty.websocket.common.WebSocketSession.incomingFrame(WebSocketSession.java:375) at org.eclipse.jetty.websocket.common.extensions.AbstractExtension.nextIncomingFrame(AbstractExtension.java:182) at org.eclipse.jetty.websocket.common.extensions.compress.PerMessageDeflateExtension.nextIncomingFrame(PerMessageDeflateExtension.java:105) at org.eclipse.jetty.websocket.common.extensions.compress.CompressExtension.forwardIncoming(CompressExtension.java:142) at org.eclipse.jetty.websocket.common.extensions.compress.PerMessageDeflateExtension.incomingFrame(PerMessageDeflateExtension.java:85) at org.eclipse.jetty.websocket.common.extensions.ExtensionStack.incomingFrame(ExtensionStack.java:220) at org.eclipse.jetty.websocket.common.Parser.notifyFrame(Parser.java:220) at org.eclipse.jetty.websocket.common.Parser.parse(Parser.java:256) at org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection.readParse(AbstractWebSocketConnection.java:679) at org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection.onFillable(AbstractWebSocketConnection.java:511) at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:279) at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:110) at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:124) at org.eclipse.jetty.util.thread.Invocable.invokePreferred(Invocable.java:128) at org.eclipse.jetty.util.thread.Invocable$InvocableExecutor.invoke(Invocable.java:222) at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:294) at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:199) at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:673) at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:591) at java.lang.Thread.run(Thread.java:745 Hopefully someone can help on this topic. Otherwise i have to discard the inline editing of the elements.

Robert

34903.jpg
34904.jpg
34905.jpg

I’ve done further investigations. My only use case is to rename a root item.
Adding a new a root item, moving items, setting a new parent and every idea i had, failed fabulous.

My last try was to remove both equals/hash methods in my bean class and now it works exactly as required. But this sounds a little bit strange.

Robert

Sounds like your equals/hashcode methods might have been buggy (creating false matches)? Have you tried autogenerating them (most IDEs have this feature), that’s usually a pretty good way to get them working as expected.

-Olli