vaadin / flow

Vaadin Flow is a Java framework binding Vaadin web components to Java. This is part of Vaadin 10+.
Apache License 2.0
600 stars 165 forks source link

ComboBoxLazyDataView does not honour setIdentifierProvider() properly -- items show twice without overridden equals/hashCode #19361

Open enver-haase opened 3 months ago

enver-haase commented 3 months ago

Description of the bug

When I say multiSelectComboBox.getLazyDataView().setIdentifierProvider( Item::getPrimaryKey )

then I still get duplicates in my lazily loaded data.

When I implement equals and hashCode, everything works as expected.

I do wonder if it's a documentation issue, but one would assume that this is exactly why he setIdentifierProvider is there in the first place, so that equals/hashCode will not be used.

Expected behavior

I should not need to implement hasCode/equals in order to not have duplicates.

Minimal reproducible example

[will follow]

Versions

enver-haase commented 3 months ago
package com.example.application.views.helloworld;

import com.example.application.views.MainLayout;
import com.vaadin.flow.component.combobox.ComboBox;
import com.vaadin.flow.component.combobox.MultiSelectComboBox;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.function.SerializableFunction;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.router.RouteAlias;

import java.util.stream.Stream;

@PageTitle("Hello World")
@Route(value = "", layout = MainLayout.class)
@RouteAlias(value = "", layout = MainLayout.class)
public class HelloWorldView extends HorizontalLayout {

    static class Foo {
        private final String privateString;

        Foo(String str) {
            this.privateString = str;
        }

        public String toString() {
            return privateString;
        }

//        @Override
//        public boolean equals(Object obj) {
//            return toString().equals(obj.toString());
//        }
//
//        @Override
//        public int hashCode() {
//            return 0;
//        }
    }

    public HelloWorldView() {
        MultiSelectComboBox<Foo> comboBox = new MultiSelectComboBox<>();
        ComboBox.FetchItemsCallback<Foo> fb = (filter, offset, limit) -> {
            Foo[] foos = {new Foo("abc"), new Foo("def"), new Foo("abc")};
            return Stream.of(foos);
        };
        comboBox.setDataProvider(fb, (SerializableFunction<String, Integer>) s -> 3);
        comboBox.getLazyDataView().setIdentifierProvider(Foo::toString);
        add(comboBox);
    }

}
mshabarov commented 1 day ago

The issue was triaged and currently added to the backlog priority queue for further investigation.