Quarkus热重载后Vaadin Bean Validation失效问题咨询
问题确认与分析
核心结论
热重载后必填指示器理应正常显示,当前出现的缺失问题属于Quarkus 3.6.3与Vaadin 24.3.0集成时,dev模式热重载导致Bean Validation元数据管理失效的bug。
问题根源
根据调试结果,问题出在Quarkus的PredefinedScopeBeanMetaDataManager实例生命周期与热重载的兼容性上:
- 初始启动时,
LazyFactoryInitializer#FACTORY常量中的CloseAsNoopValidatorFactoryWrapper持有包含实体类Bean Validation注解元数据的PredefinedScopeBeanMetaDataManager实例。 - 热重载触发后,旧实例的
beanMetaDataMap被清空,同时新实例被创建并重新加载了注解元数据,但Vaadin的BeanValidationBinder仍引用旧的、元数据为空的实例,导致configureRequired方法无法获取propertyDescriptor,最终无法渲染必填指示器和执行验证。
临时解决方法
- 强制重启应用:dev模式下遇到该问题时,直接重启应用而非依赖热重载,可恢复必填指示器正常显示。
- 手动重新初始化Binder:在视图类中添加热重载后的重新绑定逻辑,例如通过
@UIScope或监听Quarkus热重载事件,重新创建BeanValidationBinder实例并绑定字段:
@Route(value = "user", layout = MainLayout.class) @UIScope public class UserFormView extends VerticalLayout { private TextField firstName; private TextField lastName; private Binder<User> binder; public UserFormView() { initFieldsAndBinder(); } // 监听热重载事件,重新初始化组件与绑定器 @Observes void onHotReload(@SuppressWarnings("unused") HotReplacementEvent event) { removeAll(); initFieldsAndBinder(); } private void initFieldsAndBinder() { firstName = new TextField("First name"); lastName = new TextField("Last name"); binder = new BeanValidationBinder<>(User.class); binder.forField(firstName).withNullRepresentation("").bind("firstName"); binder.forField(lastName).withNullRepresentation("").bind("lastName"); binder.readBean(new User()); add(firstName, lastName); } }
长期解决方案
向Quarkus或Vaadin官方提交bug报告,提供调试信息和复现步骤,推动官方修复热重载时Bean Validation元数据实例的引用更新问题。
内容的提问来源于stack exchange,提问作者Sebastian S.
相关产品推荐
相关产品推荐

