You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vaadin 21 Grid预选中项未在UI显示,如何正确实现Grid条目预选功能?

这个问题不是Vaadin的Bug,也不是你漏了Push之类的配置,核心原因是Person实体类没有正确重写equals和hashCode方法。

Vaadin Grid前端渲染选中状态的逻辑是:拿后端标记为选中的对象,和Grid当前数据源里的所有条目做equals对比,只有匹配到的条目才会在前端显示勾选状态。你场景里两个来源的Person对象不等:

  • event.getInvolved()里的Person是查询Event时级联加载的实例
  • Grid的数据源是单独调用personRepository.findAll()查询出来的实例

两者是同一条数据库记录对应的不同Java堆对象,如果没有重写equals方法,默认用对象内存地址判断相等,Grid就认为你要选中的对象不在当前数据源里,自然不会渲染勾选。而后端的选中集合只是简单把你传入的对象加了进去,所以你点击调试按钮能拿到全部选中项。

有两种解决方案:

方案1:重写Person类的equals和hashCode方法

基于业务主键(一般是id字段)实现相等判断即可,注意不要用到懒加载的关联字段避免触发额外查询或者NPE。
如果用Lombok可以直接加注解:

@Entity
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
public class Person {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @EqualsAndHashCode.Include
    private Long id;
    // 其他字段
}

手动实现的话参考写法:

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    Person person = (Person) o;
    return id != null && id.equals(person.id);
}

@Override
public int hashCode() {
    return getClass().hashCode();
}

方案2:从Grid数据源中获取实例后再选中

如果不想修改实体的equals逻辑,可以在预选时先从Grid的数据源里找到对应ID的实例,再调用select方法:

private void updateView() {
    persons.deselectAll();
    List<Person> gridPersons = persons.getListDataView().getItems().toList();
    for (Person related : event.getInvolved()) {
        gridPersons.stream()
            .filter(p -> p.getId().equals(related.getId()))
            .findFirst()
            .ifPresent(persons::select);
    }
}

两种方案都可以解决你遇到的前端不显示预选条目的问题。

内容的提问来源于stack exchange,提问作者Chris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 21:15:06