Button in grid not refreshing

Hi,

I am Creating a custom grid and having problems while trying to update the contents. My problem is that when I press the revert button defined in configure grid method it shows it works in log, but it doesn’t refresh in the frontend.

If I change the refreshItem to refreshall it works on first press of button, but doesn’t on second. I have to press another revert button for the first one to work.

Expected behavior is for the button to change My Enum value between R and A when revert button is clicked.

Using Java 21, Spring boot 3.2.4 and Vaadin 24

@Tag("my-table")
@Slf4j
public class CustomGrid extends Composite<HorizontalLayout> {

    private Grid<Item> grid;

    private List<Item> items = Arrays.asList(
            new Item("name1", "test1", MyEnum.R, MyEnumType.One),
            new Item(null, "test2", MyEnum.R, MyEnumType.Two),
            new Item(null, "test3", MyEnum.A, MyEnumType.Three)
    );

    public CustomGrid() {
        this.grid = new Grid<>(Item.class, false);

        createLayout();
        configureGrid();
        setItems();
        getContent().add(grid);
        
    }

    public void refreshTable() {
        grid.getDataProvider().refreshAll();
    }

    public void setItems() {
        grid.setDataProvider(new ListDataProvider<>(items));
    }

    private void createLayout() {
        getContent().setSizeFull();
        getContent().setFlexGrow(2, grid);
        getContent().addClassNames("custom-grid-table");
    }

    private void configureGrid() {
        grid.addColumn(Item::getName).setHeader("name");
        grid.addColumn(Item::getURL).setHeader("URL");
        grid.addColumn(Item::getMyEnum).setHeader("My Enum");
        grid.addColumn(Item::getMyEnumType).setHeader("My Enum Type");
        grid.addComponentColumn(item -> new Button("Revert", new Icon(VaadinIcon.REFRESH), buttonClickEvent -> {
            var newMyEnum = Item.getMyEnum().equals(MyEnum.A) ? MyEnum.R : MyEnum.A;
            log.info("old: {}", item);
            item.setMyEnum(newMyEnum);
            log.info("new: {}", item);
            grid.getDataProvider().refreshItem(item);
        })).setHeader("Revert");
    }

    public void addItem(Item item) {
        items.add(item);
    }
}

Just a guess: you don’t have proper equals and hashcode methods in your Pojos. Those have to stay static for the Grid to match your row / changed object.

I use Lombok Data annotation to generate those, but after you said that I removed it and made them by hand and it still doesn’t work.

Only include the ID of your Pojos and it should work.

What do you mean by id?
This is the class:

@Data
@AllArgsConstructor
public class Item {

    private final String name;
    private final String URL;
    private MyEnum myEnum;
    private final MyEnumType myEnumType;
}

The @Data annotation is evil. To be more specific, the default equals/hashCode implmementations Lombok generates. If you use those and mutate your objects they will be in every HashMap and HashSet; and many Vaadin components.

Use either only @Getter and @Setter annotations or fix the equals/hashCode implementaion to use those final fields you appear to have in your domain objects.

3 Likes