0

0

Vaadin Grid:解决“同一属性存在多个列”异常

碧海醫心

碧海醫心

发布时间:2025-08-18 17:36:02

|

840人浏览过

|

来源于php中文网

原创

Vaadin Grid:解决“同一属性存在多个列”异常

本文旨在解决Vaadin Grid在使用实体类初始化时遇到的“同一属性存在多个列(Multiple columns for the same property)”异常。该问题通常源于Vaadin Grid的自动列生成机制与手动添加列操作的冲突。教程将详细解释异常原因,并提供两种有效的解决方案:利用Vaadin的自动列生成功能或完全手动控制列的创建,以避免重复定义。

理解Vaadin Grid的列生成机制

vaadin grid是一个功能强大的数据表格组件,它提供了多种定义列的方式。当通过构造函数传入一个实体类(例如 new grid<>(audit.class))时,vaadin grid会默认检查该实体类的所有属性(通过getter方法反射获取),并为每个属性自动生成一个对应的列。这是vaadin为了简化开发而提供的一个便利功能,它会为 auditid、trip、user、enterprise 等属性自动创建列。

然而,如果在此之后,开发者又手动调用 grid.addColumns("propertyName") 方法为同一个属性添加列,就会导致冲突。Vaadin Grid检测到同一个属性(例如 auditId)被尝试创建两次列时,就会抛出 java.lang.IllegalArgumentException: Multiple columns for the same property 异常。

在提供的代码示例中,EnterpriseView 类的构造函数中存在以下两行关键代码:

this.grid = new Grid<>(Audit.class); // 这一行会自动为Audit类的所有属性创建列,包括auditId
// ...
grid.addColumns( "auditId" ); // 这一行又尝试手动添加一个名为"auditId"的列

正是第二行 grid.addColumns("auditId") 导致了异常,因为它试图重复定义一个已经由 new Grid<>(Audit.class) 自动创建的列。

解决方案

解决此问题有两种主要方法,具体取决于您希望如何控制Grid的列显示。

方法一:利用Vaadin的自动列生成(推荐)

如果您希望Grid自动显示实体类的所有或大部分属性,并且只需要对某些列进行微调,那么最简单的方法是完全依赖 new Grid<>(Audit.class) 的自动生成功能,并移除任何重复的 addColumns 调用。

示例代码:

Favird
Favird

极其棒且有价值的互联网资源目录!

下载
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.*;
import com.wtd.assistant.frontend.dao.AuditDao;
import com.wtd.assistant.frontend.dao.EnterpriseDao;
import com.wtd.assistant.frontend.domain.Audit;
import com.wtd.assistant.frontend.domain.Enterprise;

import java.util.List;
import java.util.Optional;

@Route("EnterpriseView")
public class EnterpriseView extends VerticalLayout implements HasUrlParameter<String>, AfterNavigationObserver{

    private EnterpriseDao enterpriseDao;
    private AuditDao auditDao;
    private Grid<Audit> grid;
    private List<Audit> auditsList;
    private Optional<Enterprise> enterprise;
    private String enterpriseId;

    public EnterpriseView(EnterpriseDao enterpriseDao, AuditDao auditDao) {
        this.enterpriseDao = enterpriseDao;
        this.auditDao = auditDao;
        // 仅通过类初始化Grid,Vaadin会自动生成列
        this.grid = new Grid<>(Audit.class); // 此时auditId列已经存在

        VerticalLayout layout = new VerticalLayout();
        layout.add(grid);
        // 移除重复的 grid.addColumns("auditId");
        // 如果需要自定义列的顺序或可见性,可以在这里进行操作,例如:
        // grid.setColumns("auditId", "trip", "user", "enterprise"); // 指定显示的列及其顺序
        // grid.getColumnByKey("auditId").setHeader("审计ID"); // 修改列头
    }

    @Override
    public void setParameter(BeforeEvent event, String parameter) {
        enterpriseId = parameter;
        System.out.println("setParameter(), enterpriseId: " + enterpriseId);
    }

    @Override
    public void afterNavigation(AfterNavigationEvent event) {
        enterprise = enterpriseDao.findById(Integer.valueOf(enterpriseId));
        System.out.println("EnterpriseId: " + enterprise.get().getEnterpriseId());
        auditsList = enterprise.get().getAudits();
        grid.setItems(auditsList);
    }
}

注意事项:

  • 使用 grid.setColumns("property1", "property2", ...) 方法可以指定Grid显示的列以及它们的顺序。未列出的属性将不会显示。
  • 可以通过 grid.getColumnByKey("propertyName").setHeader("New Header") 来修改自动生成列的标题。
  • 对于关联实体(如 Trip, User, Enterprise),Vaadin Grid默认会显示它们的 toString() 方法结果。如果需要显示关联实体的特定属性(例如 enterprise.name),需要使用 addColumn 配合 ValueProvider 或 Renderer。

方法二:完全手动控制列的创建

如果您不希望Grid自动生成任何列,而是希望完全手动地添加和配置每一列,那么可以在初始化Grid时不传入实体类,然后逐个添加所需的列。

示例代码:

import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.router.*;
import com.wtd.assistant.frontend.dao.AuditDao;
import com.wtd.assistant.frontend.dao.EnterpriseDao;
import com.wtd.assistant.frontend.domain.Audit;
import com.wtd.assistant.frontend.domain.Enterprise;

import java.util.List;
import java.util.Optional;

@Route("EnterpriseView")
public class EnterpriseView extends VerticalLayout implements HasUrlParameter<String>, AfterNavigationObserver{

    private EnterpriseDao enterpriseDao;
    private AuditDao auditDao;
    private Grid<Audit> grid;
    private List<Audit> auditsList;
    private Optional<Enterprise> enterprise;
    private String enterpriseId;

    public EnterpriseView(EnterpriseDao enterpriseDao, AuditDao auditDao) {
        this.enterpriseDao = enterpriseDao;
        this.auditDao = auditDao;
        // 不传入实体类,Grid初始化时不会自动生成任何列
        this.grid = new Grid<>(); 

        VerticalLayout layout = new VerticalLayout();
        layout.add(grid);

        // 手动添加所有需要的列
        grid.addColumn(Audit::getAuditId).setHeader("审计ID");
        // 对于关联实体,需要指定如何显示其属性
        grid.addColumn(audit -> audit.getTrip() != null ? audit.getTrip().getTripName() : "").setHeader("行程名称");
        grid.addColumn(audit -> audit.getUser() != null ? audit.getUser().getUserName() : "").setHeader("用户名称");
        grid.addColumn(audit -> audit.getEnterprise() != null ? audit.getEnterprise().getEnterpriseName() : "").setHeader("企业名称");
        // 如果需要显示所有自动生成的列,但又想手动控制,可以这样:
        // grid.addColumns("auditId", "trip", "user", "enterprise"); // 此时不会报错,因为Grid最初是空Grid
    }

    @Override
    public void setParameter(BeforeEvent event, String parameter) {
        enterpriseId = parameter;
        System.out.println("setParameter(), enterpriseId: " + enterpriseId);
    }

    @Override
    public void afterNavigation(AfterNavigationEvent event) {
        enterprise = enterpriseDao.findById(Integer.valueOf(enterpriseId));
        System.out.println("EnterpriseId: " + enterprise.get().getEnterpriseId());
        auditsList = enterprise.get().getAudits();
        grid.setItems(auditsList);
    }
}

注意事项:

  • 当使用 new Grid<>() 初始化时,Grid是空的,不会有任何默认列。
  • 您需要使用 grid.addColumn(ValueProvider<ITEM, VALUE>) 或 grid.addColumn(String propertyName) 等方法逐个添加列。
  • 对于复杂属性(如关联实体),使用 ValueProvider(例如 Audit::getAuditId 或 Lambda表达式 audit -> audit.getTrip().getTripName())可以精确控制列中显示的内容。
  • 这种方法提供了最大的灵活性,可以完全控制列的显示名称、值格式、排序、过滤等。

总结

“Multiple columns for the same property”异常是Vaadin Grid中常见的配置错误,它提醒开发者注意Grid的列生成机制。核心在于避免对同一个实体属性进行重复的列定义。通过选择适合您需求的列管理策略——无论是依赖Vaadin的智能自动生成,还是进行精细的手动控制——都可以有效地解决此问题并构建出清晰、功能完善的数据表格。在实际开发中,推荐根据项目需求和团队习惯选择最合适的方案,并始终保持对Vaadin Grid列配置的清晰理解。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

1030

2023.08.02

lambda表达式
lambda表达式

Lambda表达式是一种匿名函数的简洁表示方式,它可以在需要函数作为参数的地方使用,并提供了一种更简洁、更灵活的编码方式,其语法为“lambda 参数列表: 表达式”,参数列表是函数的参数,可以包含一个或多个参数,用逗号分隔,表达式是函数的执行体,用于定义函数的具体操作。本专题为大家提供lambda表达式相关的文章、下载、课程内容,供大家免费下载体验。

215

2023.09.15

python lambda函数
python lambda函数

本专题整合了python lambda函数用法详解,阅读专题下面的文章了解更多详细内容。

192

2025.11.08

Python lambda详解
Python lambda详解

本专题整合了Python lambda函数相关教程,阅读下面的文章了解更多详细内容。

61

2026.01.05

class在c语言中的意思
class在c语言中的意思

在C语言中,"class" 是一个关键字,用于定义一个类。想了解更多class的相关内容,可以阅读本专题下面的文章。

871

2024.01.03

python中class的含义
python中class的含义

本专题整合了python中class的相关内容,阅读专题下面的文章了解更多详细内容。

32

2025.12.06

Python异步编程与Asyncio高并发应用实践
Python异步编程与Asyncio高并发应用实践

本专题围绕 Python 异步编程模型展开,深入讲解 Asyncio 框架的核心原理与应用实践。内容包括事件循环机制、协程任务调度、异步 IO 处理以及并发任务管理策略。通过构建高并发网络请求与异步数据处理案例,帮助开发者掌握 Python 在高并发场景中的高效开发方法,并提升系统资源利用率与整体运行性能。

37

2026.03.12

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

135

2026.03.11

Go高并发任务调度与Goroutine池化实践
Go高并发任务调度与Goroutine池化实践

本专题围绕 Go 语言在高并发任务处理场景中的实践展开,系统讲解 Goroutine 调度模型、Channel 通信机制以及并发控制策略。内容包括任务队列设计、Goroutine 池化管理、资源限制控制以及并发任务的性能优化方法。通过实际案例演示,帮助开发者构建稳定高效的 Go 并发任务处理系统,提高系统在高负载环境下的处理能力与稳定性。

47

2026.03.10

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
10分钟--Midjourney创作自己的漫画
10分钟--Midjourney创作自己的漫画

共1课时 | 0.1万人学习

Midjourney 关键词系列整合
Midjourney 关键词系列整合

共13课时 | 0.9万人学习

AI绘画教程
AI绘画教程

共2课时 | 0.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号