Which EJB to use? Stateful, stateless and singleton session beans compared

When developing a service layer, Java architects are often challenged with which of the three session beans, stateful, stateless or singleton, should be used.

A common question enterprise architects are perpetually faced with when developing a distributed architecture is which types of EJBs should they use, or more specifically, when developing a solution that uses session EJBs, should the design use stateless session beans or stateful session beans. Sadly, the quandary has become even more complicated since the release of EJB 3.1 with the introduction an entirely new session bean known as the singleton.

Using stateful session beans

The Singleton design pattern is one of the oldest design patterns around, but it is deceptively difficult to code effectively.

Lukas Stewart, Enterprise Software Architect

The stateful session bean has been derided for years due to the inconsistency between vendors over how failover of state is performed. The specification doesn't require stateful session beans to be capable of failing over from one server to another, and that has scared off more than one or two enterprise architects in the past. However, clustering and failover for stateful session beans can be configured for just about every major application server on the market, be it IBM's WebSphere or the open-source Glassfish server.

So with the failover issue put aside, when should a stateful session bean be used? Stand-alone applications that don't have any internal state-management facilities are a good option for stateful session beans. Mobile devices with very limited client-side memory also create a compelling argument for using stateful session beans. Basically, if you are working with a client that does not have access to the HTTP protocol that allows state to be managed through an HttpSession, then stateful session beans are a good choice.

Stateful session beans are by definition tied to a single client, so for each new client that requests its services, a new instance is created. On the other end of the spectrum is the new singleton session bean. Introduced in EJB 3.1, any EJB decorated with the @Singleton annotation will be managed in such a way that only one instance of the class will ever be created. This one instance is then shared by each and every client that requires its services.

@Stateful
@Local(CoinLockerLocal.class)
@Remote(CoinLockerRemote.class)
@LocalBean
public class CoinLocker 
       implements CoinLockerRemote, CoinLockerLocal {

    private String coinToken;
	
    public CoinLocker() {   }
 
}

Introducing the singleton session bean

The singleton design pattern is one of the oldest design patterns around, but it is deceptively difficult to code effectively due to the fact that enterprise applications use a multitude of classloaders. While a piece of software might look like it would only ever spawn one instance, web modules, JPA layers and embedded components may each create instances depending upon how a given application is packaged. The @Singleton session bean takes the guesswork out of implementing the singleton pattern at an enterprise scale.

So when should a singleton session bean be used? According to its definition, you use a singleton any time you want one and only one instance of a given class to be created. This often applies to utility classes or components that provide access to external resources that may get swamped if a multitude of connections are attempted at once. If you only want one instance of a class to be created, regardless of how many clients access the resource, the singleton session bean is the right component to choose.

@Singleton
@Local(MasterUtilLocal.class)
@Remote(MasterUtilRemote.class)
@LocalBean
public class MasterUtil 
       implements MasterUtilRemote, MasterUtilLocal {

	
    public MasterUtil() {   }

}

Creating facades with the stateless session

So with the singleton and stateful session beans accounted for, the discussion circles back to the question of when is the right time to use the stateless session bean?

Stateless session beans are the component of choice for creating a front door to your back-end systems. When requests have been processed by the web layer, and back end resources are required, whether it's a matter of writing a message to a message queue, or persisting data using the Java Persistence API, the stateless session bean is the component that should orchestrate all of this.

@Stateless
@Local(ValetServiceLocal.class)
@Remote(ValetServiceRemote.class)
@LocalBean
public class ValetService 
         implements ValetServiceRemote, ValetServiceLocal {

    @PersistenceContext(unitName = "ValetData")
    private EntityManager entityManager;

    public ValetService() {   }

}

Now it is key that the stateless session bean should orchestrate the interaction with back-end resources. The stateless session bean should not contain a terribly large amount of code, or try to perform too many functions. Instead, the stateless session bean should delegate work to other components in the backend. It has been said that back-end resources such as JPA entities, persistent components, file system writers and message queues are like actors in a play, while a stateless session bean should play the role of the script, instructing the various actors when to get involved, and how to interact with each other.

Essentially, stateless session beans are perfect for implementing what is known as the session facade design pattern. The Session Facade is well documented, as it is a key construct in practically every Java based distributed system. The J2EE Core Patterns book, which will likely be rewritten as Java EE Core Patterns sometime soon, states the following as benefits to using a stateless session bean to implement the session facade pattern:

  • Introduces a layer that provides services to remote clients
  • Exposes a uniform coarse-grained interface
  • Reduces coupling between the tiers
  • Promotes layering, increases flexibility and maintainability
  • Reduces complexity
  • Improves performance, reduces fine-grained remote methods
  • Centralizes security management
  • Centralizes transaction control
  • Exposes fewer remote interfaces to clients

Of course, a good enterprise architect will realize that there are many cases where none of these options are the correct one. The POJO based approach to EJB development in version 3.1 certainly simplifies the development of enterprise JavaBeans, but not every solution requires both an EJB and the services of the enterprise container that manages their lifecycle and mitigates client access to them. Remote access to enterprise services, security down to the method level and annotation based transaction demarcation are all compelling reasons to leverage the facilities of EJBs in your code, but anyone who has played with Occam's razor knows that the simplest solution is always the best one. But if you do need to use EJBs in your distributed solution, there is a wealth of options for you to employ, and hopefully this discussion has provided some important insight into which session based EJB is the best one to use in a given situation.

Let us know your best practices for using session EJBs in your applications.

You should follow Cameron McKenzie on Twitter: @cameronmcnz

Interested in more articles and opinion pieces from Cameron McKenzie? Check these out:

Dig Deeper on Core Java APIs and programming techniques