Dependency injection is magic, some say. It is magic, especially if you don’t understand what is happening behind the scenes. Vaadin developers have two almost identical scopes available for their beans: SessionScope (from Spring core) and VaadinSessionScope (from vaadin-spring). Picking the wrong one sometimes causes the magic to break. Recently I got a request to help in a situation where the Vaadin application threw an exception like this:
Caused by:java.lang.IllegalStateException:
No thread-bound request found: Are you referring to request attributes outside of an actual web request or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet:
In this case, useRequestContextListener
orRequestContextFilter
to expose the current request.
The solution was to change the scope. Let’s look into the differences between these two scopes and which one you should pick.
Comparing SessionScope with VaadinSessionScope
SessionScope is a default scope provided by the Spring Core. In the JavaDocs, it is summarized like this:
SessionScope is a specialization of Scope for a component whose lifecycle is bound to the current web session.
Its implementation is related to the Servlet session, accessed through servlet requests. Spring stores the request as a “thread local.” The exception above happened because the bean was accessed outside a thread handling an HTTP request.
VaadinSessionScope is closely related to the SessionScope. However, it is provided by the Vaadin Spring integration and is more specific. In the JavaDocs, VaadinSessionScope is summarized like this:
Implementation of Spring's Scope that binds the beans to the current VaadinSession (as opposed to the current Servlet session.
Similarly to the SessionScope, VaadinSessionScope is not always active but activated by Vaadin itself (or technically by Spring/CDI integrations), for example, always when executing event listeners triggered by the user.
@Push is when scope actually matters
It doesn’t matter which of the two annotations you choose for most use cases. But there are two cases when it matters: modifying Vaadin UI from another thread (~ server push) and integrating with other Spring things.
For applications utilizing Vaadin’s sophisticated server push, VaadinSessionScope is superior. Because the Vaadin integrations are handling it, we can extend the activity of the scope from the limitation Spring’s built-in SessionScope has (active request). Thus, VaadinSessionScope(d) bean is active, also, when modifying your UI from another thread via the UI.access()
method, which you should always use to ensure proper locking of the UI.
The downside of VaadinSessionScope is that it is not Spring’s SessionScope. VaadinSessionScope might be incompatible with some APIs you are using. Even in the same application, you might use Spring MVC for static views and Vaadin for more advanced UIs. If you want to share a bean with both apps, SessionScope should be your choice.
Decision matrix and summary
SessionScope | VaadinSessionScope | |
Store session-wide settings or cached data | ✅ | ✅ |
Use with any servlet-based web technologies | ✅ | - |
Use with basic Vaadin usage | ✅ | ✅ |
Works with @Push (when used with UI.access()) | - | ✅ |
If your session-scoped bean is only to be used in a Vaadin application, you are probably always better off choosing VaadinSessionScope. Using it, you are safe if you, for example, add external updates delivered with server push later. Pick the more generic SessionScope if your bean is also used in non-Vaadin modules.
Note: In the Vaadin CDI integration, there is a similar VaadinSessionScoped annotation and SessionScoped in the CDI specification itself. The same principles apply to those.