Update grid on entity update

I’m developing my application using Flow only, no ts/React/other languages, only Java. I have this entity:

@Getter
@Setter
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Entity
public class SomeModel {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String name;
    private Integer age;

    public SomeModel(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public final boolean equals(Object o) {
        if (this == o) return true;
        if (o == null) return false;
        Class<?> oEffectiveClass = o instanceof HibernateProxy ? ((HibernateProxy) o).getHibernateLazyInitializer().getPersistentClass() : o.getClass();
        Class<?> thisEffectiveClass = this instanceof HibernateProxy ? ((HibernateProxy) this).getHibernateLazyInitializer().getPersistentClass() : this.getClass();
        if (thisEffectiveClass != oEffectiveClass) return false;
        SomeModel someModel = (SomeModel) o;
        return getId() != null && Objects.equals(getId(), someModel.getId());
    }

    @Override
    public final int hashCode() {
        return this instanceof HibernateProxy ? ((HibernateProxy) this).getHibernateLazyInitializer().getPersistentClass().hashCode() : getClass().hashCode();
    }
}

and this grid in my view:

this.grid = new Grid<>(SomeModel.class, false);
grid.addColumn(SomeModel::getId).setHeader("ID");
grid.addColumn(SomeModel::getName).setHeader("Name");
grid.addColumn(SomeModel::getAge).setHeader("Age");
grid.addComponentColumn(someModel -> new Button("delete", event -> {
    someModelService.removeModel(someModel.getId());
    this.getUI().ifPresent(ui -> ui.access(this::updateModels));
})).setHeader("Delete");
grid.setAllRowsVisible(true);
grid.addThemeVariants(GridVariant.LUMO_ROW_STRIPES);
grid.addClassName("my-grid");

I want this grid to be updated each time my database table updates, on deletes/updates/saves… I used @EntityListeners, but I don’t know how I can access this particular view from other bean/class. My view contains autowired SomeModelRepository, and when I tried to add @PostPersist annotation on updateModels() method inside of my view and pass my view as a parameter to @EntityListener, cycled dependency exception occured. I’m pretty new to Vaadin, so I don’t know how to properly access views from other components and update their UI.

Currently I use scheduler to update grid every second, but it doesn’t seem as a good thing…

Rather than directly referencing the view from the entity listener callback, I would recommend introducing an indirection in the form of firing an event that the view can listen to. The reason for this is that there are multiple instances of the view if there are multiple users or if one user has the view open in multiple browser tabs. Each view instance needs to manage its own life cycle.

There are various examples of this pattern in How to use Server Push in your Vaadin application and How to enable server push in Vaadin applications.

1 Like