Differences : @SessionScoped vs @Stateful and @ApplicationScoped vs @Singleton

Gugelhupf picture Gugelhupf · Jun 8, 2014 · Viewed 11.6k times · Source

I would like to know, what are the principal differences between :

  1. javax.enterprise.context.SessionScoped and javax.ejb.Stateful
  2. javax.enterprise.context.ApplicationScoped and javax.ejb.Singleton

I know that a @SessionScoped and a @Stateful allows to create a new instance for each client. I also know that for the @ApplicationScoped and @Singleton / @Stateless they are shared between the clients.

=> But when should I consider it's better to choose an EJB, or the other?

Answer

Arjan Tijms picture Arjan Tijms · Jun 9, 2014

@SessionScoped denotes a scope while @Stateful is in a way what we would now call a stereotype. @Stateful adds a number a services to a bean, among which transactional behavior and passivation.

Central to @Stateful is however its session behavior, which indeed overlaps with the session scope.

The difference is that the session scope is tied to the HTTP session, while @Stateful is an open-ended user managed session, with its lifetime managed by a client that has a reference to the bean proxy.

@Stateful remote beans where originally the binary (RMI) counter parts of Servlets. Where Servlets listened to remote HTTP requests from a browser, @Stateful remote beans listened to remote RMI requests from Applets (and later Swing clients).

There were unfortunately many inconsistencies between the two. A Servlet was just an HTTP listener, while @Stateful beans automatically brought in a lot of other features. A Servlet also shared the session with all other Servlets and also shared the Java EE component namespace with all other Servlets in a war, while with the @Stateful EJB every separate bean has its own session and component namespace.

With the introduction of local beans in EJB 2 and a sharp decline of Swing/Applet clients for remote EJB communication, the function of the session that's maintained for an @Stateful bean has become less clear.

I think it's fair to say that @Stateful simply isn't used that much these days. For a web application the HTTP session is almost always leading, which means using the session scope and local @Stateless beans and/or CDI beans for business logic.

In some cases @Stateful beans are needed for their natural support for the extended persistence context from JPA and for their passivation features (Servlet doesn't have a standardized passivation mechanism). Note that @Stateful and @SessionScoped (or many other scopes) can be combined. The advantage of combining them is that user code no longer needs to manage the lifetime, but the container manages this.

There's a somewhat similar story for @ApplicationScoped and @Singleton, although without the legacy (@Singleton is a fairly new thing). @ApplicationScoped is just a scope, while @Singleton is a bean type (stereotype if you wish), which doesn't only give you application scoped behavior, but also provides you with transactional behavior again, with automatic locking (which can be tuned via @Lock) and with eager construction behavior (via @Startup).

Although @Stateful and @Singleton are by themselves pretty handy, the current way forward in Java EE seems to be to decompose those build-in stereotypes into separately useable annotations and who knows, perhaps one day they will be actual CDI stereotypes consisting of those decomposed annotations.