Grid editor gives "The item xxxx is not in the backing data provider" after adding row to ListDataProvider

I have a Grid with a ListDataProvider.
If Grid has many rows, adding a new row at the end, and editing it, gives:

 java.lang.IllegalStateException: The item xxxx is not in the backing data provider
    at deployment.ptsmc.ear//com.vaadin.flow.component.grid.editor.EditorImpl.validate(EditorImpl.java:221)
    at deployment.ptsmc.ear//com.vaadin.flow.component.grid.editor.EditorImpl.requestEditItem(EditorImpl.java:147)
    at deployment.ptsmc.ear//com.vaadin.flow.component.grid.editor.EditorImpl.lambda$editItem$2d5ea2ce$1(EditorImpl.java:137)
    at deployment.ptsmc.ear//com.vaadin.flow.internal.StateTree.lambda$runExecutionsBeforeClientResponse$2(StateTree.java:397)
    at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
    at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
    at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
    at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
    at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
    at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596)
    at deployment.ptsmc.ear//com.vaadin.flow.internal.StateTree.runExecutionsBeforeClientResponse(StateTree.java:392)
    at deployment.ptsmc.ear//com.vaadin.flow.server.communication.UidlWriter.encodeChanges(UidlWriter.java:394)
    at deployment.ptsmc.ear//com.vaadin.flow.server.communication.UidlWriter.createUidl(UidlWriter.java:170)
    at deployment.ptsmc.ear//com.vaadin.flow.server.communication.UidlRequestHandler.createUidl(UidlRequestHandler.java:155)
    at deployment.ptsmc.ear//com.vaadin.flow.server.communication.UidlRequestHandler.writeUidl(UidlRequestHandler.java:145)
    at deployment.ptsmc.ear//com.vaadin.flow.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:115)
    at deployment.ptsmc.ear//com.vaadin.flow.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:40)
    at deployment.ptsmc.ear//com.vaadin.flow.server.VaadinService.handleRequest(VaadinService.java:1574)
    at deployment.ptsmc.ear//com.vaadin.flow.server.VaadinServlet.service(VaadinServlet.java:398)
    ...

I add row to the collection behind ListDataProvider, call ListDataProvider.refreshAll(), then open the editor on the new row.

If I start out with fewer rows in ListDataProvider, it works just fine. <20 works fine. >200 gives error.
If I insert the row at the start, it also works fine.

So, looks like a bug, but just wondered if anyone had a workaround

My first guess is that there is something wrong with object identity.

1 Like

You are not talking about implementing equals/hashCode I hope?
I don’t override those, so the only object a row is equal to is its own instance.
Just to be sure I did try adding a unique id and equals to the example below, but nothing changed.

Here is an example.
With 50 rows it fails.
With 49 rows it works.
( Vaadin 24.3.12, WIndows 10, Firefox 126.0.1 )

@Route
public class TestGridInsert extends VerticalLayout {

    public static class Row {

        String name;

        Row(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

    }

    public TestGridInsert() {

        // Data

        var rows = new ArrayList<Row>();

        for(int i=0; i<50; i++) {
            rows.add(new Row("John Doe " + i));
        }

        // Grid with editor

        var grid = new Grid<Row>(rows);
        var namecol = grid.addColumn(Row::getName).setHeader("Name");
        grid.setSizeFull();

        var binder = new Binder<>(Row.class);
        var editor = grid.getEditor();
        editor.setBinder(binder);

        TextField nameField = new TextField();
        nameField.setWidthFull();

        binder.forField(nameField)
                .bind(Row::getName, Row::setName);
        namecol.setEditorComponent(nameField);

        // Button to add new row

        var addRowButton = new Button("Add", event -> {
            var newRow = new Row("Jane Doe");
            rows.add(newRow);
            grid.getDataProvider().refreshAll();
            grid.getEditor().editItem(newRow);
        });

        //

        setSizeFull();
        add(addRowButton, grid);

    }

}

Registered bug:

It could be a corner case bug, thanks for reporting. 50 is the default page size of the Grid. So if you have 50 rows there and add 51st row and call to open the Editor, the Grid should fetch the next page of items from the server (one row in this case) and open it for editing. Something goes wrong, which needs more debugging.