Vaadin Spring Boot:多个用户访问 UI 时“无法在不锁定会话的情况下访问 VaadinSession 或 UI 中的状态”

tig*_*igu 1 java vaadin spring-boot vaadin-flow

我有一个带弹簧靴的 vaadin flow (13) 应用程序。我有一个 VerticalLayout,@UIScope用多个子布局注释。子布局@Scope("prototype")通过ctx.getBean(SubUI.class, ...). 根据父 UI (VerticalLayout) 上的选择和按钮单击,添加或删除子布局。

只要我单独使用该应用程序,一切都可以正常工作(这就是我在将应用程序交付给我的客户进行验收测试后现在发现错误的原因)。他们对多个用户进行了测试。只要有一个用户使用该应用程序,一切都正常,但是一旦第二个用户进入 UI (VerticalLayout),就会抛出以下异常:

java.util.concurrent.ExecutionException: java.lang.IllegalStateException: Cannot access state in VaadinSession or UI without locking the session.
    at java.util.concurrent.FutureTask.report(FutureTask.java:122) ~[na:1.8.0_202]
    at java.util.concurrent.FutureTask.get(FutureTask.java:192) ~[na:1.8.0_202]
    ...
Run Code Online (Sandbox Code Playgroud)

我为我的父布局尝试了不同的注释(@UIScope、@Scope("prototype")、@VaadinSessionScope)但没有解决我的错误。

我用谷歌搜索了这个问题并找到了一些线索,但没有一个能帮助我解决我的问题。我不确定问题是由我的 UI/布局的范围引起的,还是由数据绑定引起的。在我的子布局中,数据使用Binder<MyEntity> binder = new Binder<>(MyEntity.class);和绑定binder.forField(xxx).bind(MyEntity::getXY,MyEntity::setXY);

有人可以解释我,我的问题是什么?我会很高兴,因为我需要为我的客户测试提供一个固定版本。

亲切的问候

Tat*_*und 5

您的应用程序中有一些逻辑试图从后台线程修改 UI 状态、组件等。这应该通过锁定来保护。所以你需要在你的视图中封装从后台方法调用的逻辑

getUI().ifPresent(ui -> ui.access(() -> {
    ...
}));
Run Code Online (Sandbox Code Playgroud)

  • @tigu 在 clicklistener 中,您不必封装对 ui 的修改。您只需在手动启动自己的“线程”时执行此操作。您在“后台”线程中对 ui 所做的每项修改都必须被封装。另请参阅:[异步更新](https://vaadin.com/docs/v10/flow/advanced/tutorial-push-access.html)。您是否在您认为的某个地方开始了自己的主题? (2认同)