question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

When editing an updating Grid, I get exception..

See original GitHub issue

I’ve been trying to figure out, what is wrong in my code. When I go to edit some of the data in grid, I get this exception…

10:03:03.833 [qtp279680875-909] ERROR c.vaadin.server.DefaultErrorHandler - 
java.lang.IllegalStateException: Duplicate key Person(firstName=matti222, lastName=meikalainen22, sotu=111111)
        at java.util.stream.Collectors.lambda$throwingMerger$0(Collectors.java:133)
        at java.util.HashMap.merge(HashMap.java:1245)
        at java.util.stream.Collectors.lambda$toMap$58(Collectors.java:1320)
        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:481)
        at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
        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.ui.AbstractListing$AbstractListingExtension.refresh(AbstractListing.java:122)
        at com.vaadin.ui.components.grid.EditorImpl.save(EditorImpl.java:250)
        at com.vaadin.ui.components.grid.EditorImpl$1.save(EditorImpl.java:133)
        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:498)
        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.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:90)
        at com.vaadin.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:41)
        at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1577)
        at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:381)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
        at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:812)
        at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1669)
        at org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter.doFilter(WebSocketUpgradeFilter.java:224)
        at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
        at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:585)
        at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
        at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:577)
        at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:223)
        at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127)
        at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515)
        at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
        at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061)
        at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
        at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:215)
        at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
        at org.eclipse.jetty.server.Server.handle(Server.java:499)
        at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:311)
        at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257)
        at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:544)
        at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)
        at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)
        at java.lang.Thread.run(Thread.java:745)

And here is the code I’m using:

data class Person(var firstName: String, var lastName: String, var sotu: String)


/**
 * Person View
 */


@AutoView("")
class TestView: VerticalLayout(), View {


    private lateinit  var personGrid: Grid<Person>
    private lateinit  var firstNameFilter: TextField
    var persons = listOf<Person>(Person("matti", "meikalainen", "111111"), Person("teppo", "testaajaa", "2222222"))

    companion object {
        fun navigateTo() = navigateToView<WelcomeView>()
    }

    init {

        var personsListProvider = ListDataProvider<Person>(persons).withConfigurableFilter()


        isMargin = false
        label("Vaadin On Kotlin testview") {
            w = fillParent
            addStyleNames(ValoTheme.LABEL_H1, ValoTheme.LABEL_COLORED)
        }


        personGrid = grid(Person::class, "List of Persons", dataProvider = personsListProvider) {
            expandRatio = 1f;
            setSizeFull()

            val binder: Binder<Person> = getEditor().getBinder()

            column(Person::firstName) {
                caption="firstname"
                setEditorComponent(TextField("firstname"), Person::firstName.setter)
               isEditable = true
                isHidden = false
            }




            column(Person::lastName) {
                setEditorComponent(TextField("lastname"), Person::lastName.setter)
                isEditable = true
            }

            column(Person::sotu) {
                setEditorComponent(TextField("sotu"), Person::sotu.setter)
                isEditable = true

            }

            editor.addCancelListener( { event -> Notification.show("Editing Cancelled...")
            } )
            editor.addSaveListener({ event ->
                Notification.show("Saving ${event.bean.firstName} - ${event.bean.lastName} - ${event.bean.sotu} -...")
                binder.writeBean(event.bean)

                personsListProvider.refreshAll()

                // just for debugging to see what's in the provider now..
                personsListProvider.getAll().forEach(
                        {
                            println("${it.firstName} - ${it.lastName} - ${it.sotu}")
                        }
                )

                refresh()

            })

            editor.setSaveCaption("Tallenna")
            editor.setCancelCaption("Peruuta")

            editor.setEnabled(true)

            addColumn({ "Show" }, ButtonRenderer<Person>({ event -> personGrid.refresh() }))
            addColumn({ "Edit" }, ButtonRenderer<Person>({ event -> null }))
            addColumn({ "Delete" }, ButtonRenderer<Person>({ event -> null }))

            // automatically create filters, based on the types of values present in particular columns.
            appendHeaderRow().generateFilterComponents(this, Person::class)


        }

        personGrid.addItemClickListener({ event -> Notification.show("Value: " + event.getItem()) })

    }


    override fun enter(event: ViewChangeListener.ViewChangeEvent?) {
        personGrid.dataProvider.refreshAll()
    }

}

Even if I leave the whole ListDataProvider out of it, I still get the same duplicate key error. So I’m starting to wonder, is this a bug in Vaadin, or am I just doing something wrong? Is the problem with ListDataProvider, or with the Binder? I’m just not getting it how to use this properly through the docs…

Issue Analytics

  • State:open
  • Created 6 years ago
  • Comments:9 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
DALDEIcommented, Jul 26, 2019

I have hit similar but not identical symptoms – may or may not be the same. My case, the grid started behaving very strangely but didn’t always crash – I debuged/resolved it by following the hints in the docs about unique ID’s. The DataProvider getId() uses Object.equals() in some places - basically the same rules for ‘identity’ for Java collections. Depending on the specifics of the object – in kotlin - variants on interface/class/data class, @JvmField, @JvmStatic , extension properties etc can lead to 2 objects being ‘the same’ even if they are not (or visa-versa). I solved it with a derived DataProvider with a custom getId()

NOTE: the object in question came from vok-db , where “id” is a special property that’s required for data binding and DB access. For a while I was confused that this was what was being used by DataProvider.
Note: I’ve found the ‘safest’ classes to use for Grid are ‘pure’ ‘data class’ kotlin classes with nothihng fancy. Vaadin does a ‘very good’ job at discovering properties - often ‘too good’ for kotlin - finding functions or extension properties not intended for UI puproses. I havent yet found a clean way to ignore these in general to the point that I often dynamically generate classes at runtime just to put in a grid in a reproducible/reliably way with consistent naming.

1reaction
skoudecommented, Jul 14, 2017
Read more comments on GitHub >

github_iconTop Results From Across the Web

ASPxGridView - How to show an exception message in an ...
I'm handling ASPxGridView updates manually with RowUpdating. If I run into an exception during my own save operation, how do I show that...
Read more >
GridDataBoundGrid throwing exception during edit - Syncfusion
I have a GridDataBound grid bound to an IBindingList. If a cell is edited the binder correctly sets the value of the property....
Read more >
GridView Updating from code behind throwing exception
Your code fails because when update occurs the row offering edit UI is no longer available - the row at e.RowIndex is a...
Read more >
Gridview Data editing error - MSDN - Microsoft
You normally get this error when you click the edit button and then in the codebehind do a databind before the RowEditing event...
Read more >
Common errors that may occur during editing—Help
Errors that may occur when you start editing · Projected coordinate systems · Coordinates or measures are out of bounds · The spatial...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found