You are on page 1of 7

Chapter Three

3.1. Introduction to Enterprise JavaBeans


An Enterprise JavaBeans (EJB) component, or enterprise bean, is a body of code that has
fields and methods to implement modules of business logic. You can think of an enterprise bean
as a building block that can be used alone or with other enterprise beans to execute business
logic on the Java EE server.

3.2. EJB Session Beans


Session beans are great for implementing business logic, processes, and workflow. And because
enterprise applications can be complex, the Java EE platform defines several types of EJBs. A
session bean may have the following traits:
 Stateless: The session bean contains no conversational state between methods, and any
instance can be used for any client. It is used to handle tasks that can be concluded with
a single method call.
 Stateful: The session bean contains conversational state, which must be retained across
methods for a single user. It is useful for tasks that have to be done in several steps.
 Singleton: A single session bean is shared between clients and supports concurrent
access. The container will make sure that only one instance exists for the entire
application.
The three types of session beans all have their specific features, of course, but they also have a
lot in common. First of all, they have the same programming model. As you’ll see later on, a
session bean can have a local and/or remote interface, or no interface at all. Session beans are
container-managed components, so they need to be packaged in an archive (jar, war, or ear file)
and deployed to a container.
3.2.1. Stateless Bean
In Java EE applications, stateless beans are the most popular session bean components. They are
simple, powerful, and efficient and respond to the common task of doing stateless business
processing. What does stateless mean? It means that a task has to be completed in a single
method call.
As an example, we can go back to the roots of object-oriented programming where an object
encapsulates its state and behavior. In object modeling, to persist a book to a database, you
would do something like this: create an instance of a Book object (using the new keyword), set
some values, and call a method so it could persist itself to a database. In the following code, you
can see that, from the very first line to the last one, the book object is called several times and
keeps its state:
In a service architecture, you would delegate the business logic to an external service. Stateless
services are ideal when you need to implement a task that can be concluded with a single method
call (passing all the needed parameters). Stateless services are independent, are self-contained,
and do not require information or state from one request to another. So, if you take the preceding
code and introduce a stateless service, you need to create a Book object, set some values, and
then use a stateless service to invoke a method that will persist the book on its behalf, in a single
call. The state is maintained by Book but not by the stateless service:
Book book = new Book();
book.setTitle("The Hitchhiker's Guide to the Galaxy");
book.setPrice(12.5F);
book.setDescription("Science fiction comedy series created by Douglas Adams.");
book.setIsbn("1-84023-742-2");
book.setNbOfPage(354);
statelessService.persistToDatabase(book);
Stateless session beans follow the stateless service architecture and are the most efficient
component model because they can be pooled and shared by several clients. This means that, for
each stateless EJB, the container keeps a certain number of instances in memory (i.e., a pool) and
shares them between clients. Because stateless beans have no client state, all instances are
equivalent. When a client invokes a method on a stateless bean, the container picks up an
instance from the pool and assigns it to the client. When the client request finishes, the instance
returns to the pool to be reused. This means you need only a small number of beans to handle
several clients, as shown in Figure 3-1. The container doesn’t guarantee the same instance for the
same client.
Figure 3.1. Client accessing stateless beans in a pool
3.2.2. Stateful Beans
Stateless beans provide business methods to their clients but don’t maintain a conversational
state with them. Stateful session beans, on the other hand, preserve conversational state. They are
useful for tasks that have to be done in several steps, each of which relies on the state maintained
in a previous step. Let’s take the example of a shopping cart in an e-commerce web site. A
customer logs on (her session starts), chooses a first book, adds it to her shopping cart, chooses a
second book, and adds it to her cart. At the end, the customer checks out the books, pays for
them, and logs out (the session ends). The shopping cart keeps the state of how many books the
customer has chosen throughout the interaction (which can take some time, specifically the time
of the client’s session). This interaction with a stateful component could be written as follows:

The preceding code shows exactly how a stateful session bean works. Two books are created and
added to a shopping cart of a stateful component. At the end, the checkOutShoppingCart()
method relies on the maintained state and can check out the two books. When a client invokes a
stateful session bean in the server, the EJB container needs to provide the same instance for each
subsequent method invocation. Stateful beans cannot be reused by other clients. Figure 3. 2
shows the one-to-one correlation between a bean instance and a client. As far as the developer is
concerned, no extra code is needed, as the EJB container automatically manages this one-to-one
correlation.

Figure 3.2. Client accessing stateful beans


The one-to-one correlation comes at a price because, as you might have guessed, if you have one
million clients, you will get one million stateful beans in memory. To avoid such a big memory
footprint, the container temporarily clears stateful beans from memory before the next request
from the client brings them back. This technique is called passivation and activation.
Passivation is the process of removing an instance from memory and saving it to a persistent
location (a file on a disk, a database, etc.). It helps you to free memory and release resources (a
database or JMS connections, etc.). Activation is the inverse process of restoring the state and
applying it to an instance. Passivation and activation are done automatically by the container;
you shouldn’t worry about doing it yourself, as it’s a container service. What you should worry
about is freeing any resource (e.g., database connection, JMS factories connection, etc.) before
the bean is passivated. Since EJB 3.2, you can also disable passivation.
Let’s return to the shopping-cart example and apply it to a stateful bean (ash shown in the code
below). A customer logs on to a web site, browses the catalog of items, and adds two books to
the shopping cart (addItem() method). The cartItems attribute holds the content of the cart.
Then the customer decides to get a coffee at a coffee machine. During this time, the container
might passivate the instance to free some memory, which in turn saves the shopping content to
permanent storage. A few minutes later, the customer comes back and wants to know the total
price (getTotal() method) of his shopping cart before buying anything. The container activates
the EJB and restores the data to the shopping cart. The customer can then check out (checkout()
method) and buy the books. Once the customer logs off, the customer’s session ends, and the
container frees memory by permanently removing the instance of the stateful bean.
The shopping-cart
situation is a standard
way of using stateful
beans in which the
container automatically
takes care of maintaining
the conversational state.
The only needed
annotation is
@javax.ejb.Stateful,
which has the same API
as @Stateless Notice the
optional

@javax.ejb.StatefulTimeout and @javax.ejb.Remove annotations. @Remove decorates the


checkout() method. This causes the bean instance to be permanently removed from memory
after you invoke the checkout() method. @StatefulTimeout assigns a timeout value, which is
the duration the bean is permitted to remain idle (not receiving any client invocations) before
being removed by the container. The time unit of this annotation is a
java.util.concurrent.TimeUnit, so it can go from DAYS, HOURS ... to NANOSECONDS (the
default is MINUTES). Alternatively, you can avoid these annotations and rely on the container
automatically removing an instance when the client’s session ends or expires. However, making
sure the stateful bean is removed at the appropriate moment might reduce memory consumption.
This could be critical in highly concurrent applications.
3.2.3. Singleton
A singleton bean is a session bean that is instantiated once per application. It implements the
widely used Singleton pattern from the famous book by the Gang of Four: Design Patterns:
Elements of Reusable Object-Oriented Software by Erich Gamma, Richard Helm, Ralph
Johnson, and John M. Vlissides (Addison-Wesley, 1995). A singleton ensures that only one
instance of a class exists in the whole application and provides a global point to access to it.
There are many situations that need singleton objects—that is, where your application only needs
one instance of an object: a mouse, a window manager, a printer spooler, a file system, and so
on.
Another common-use case is a caching system whereby the entire application shares a single
cache (e.g., a Hashmap) to store objects. In an application-managed environment, you need to
tweak your code a little bit to turn a class into a singleton, as shown in as shown in the code
below. First, you need to prevent the creation of a new instance by having a private constructor.
The public static method getInstance() returns the single instance of the CacheSingleton class. If
a client class wants to add an object to the cache using the singleton, it needs to call
CacheSingleton.getInstance().addToCache(myObject);
If you want this code to be thread-safe, you will have to use the synchronized keyword to
prevent thread interference and inconsistent data. Instead of a Map, you can also use a
java.util.concurrent.ConcurrentMap which will result in much more concurrent and scalable
behavior. This can be useful if those are critical considerations.
public class Cache {

private static Cache instance = new Cache();

private Map<Long, Object> cache = new HashMap<>();

private Cache() {}

public static synchronized Cache getInstance() {

return instance;

public void addToCache(Long id, Object object) {

if (!cache.containsKey(id))

cache.put(id, object);

public void removeFromCache(Long id) {

if (cache.containsKey(id))

cache.remove(id);
}

public Object getFromCache(Long id) {

if (cache.containsKey(id))
return cache.get(id);

else

return null;

}
}

EJB 3.1 introduced the singleton session bean, which follows the singleton design pattern. Once
instantiated, the container makes sure there is only one instance of a singleton for the duration of
the application. An instance is shared between several clients, as shown in Figure 3.3. Singletons
maintain their state between client invocations.

Fig 3.3 Client accessing Singleton Bean


To turn the code in Listing the above snapped shot code from a singleton Java class to a
singleton session bean (as shown in the code below), there is not much to do. In fact, you just
need to annotate a class with @Singleton and not worry about the private constructor or the
static getInstance() method. The container will make sure you create only one instance. The
@javax.ejb.Singleton annotation has the same API as the @Stateless annotation described
earlier in stateless snapped code.
As you can see, stateless, stateful, and singleton session beans are very easy to develop: you just
need one annotation. Singletons, though, have a bit more to them. They can be initialized at
startup, be chained together, and have their concurrency access customized.
3.3 Messaging and Message Driven Bean
Message-driven beans (MDBs) are used for integrating with external systems by receiving
asynchronous messages using JMS. Even though MDBs are part of the EJB specification, I deal
with them separately because this component model is mainly used to integrate systems with
message-oriented middleware (MOM). MDBs usually delegate the business logic to session
beans.

You might also like