1. Introduction
Enterprise Session Beans can be broadly classified into:
- Stateless Session Beans
- Stateful Session Beans
In this quick article, we are going to discuss these two main types of session beans.
2. Setup
To use Enterprise Beans 3.2**,** make sure to add the latest version to the dependencies section of the pom.xml file:
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
3. Stateless Beans
A stateless session bean is a type of enterprise bean which is commonly used to do independent operations. It does not have any associated client state, but it may preserve its instance state.
Let’s have a look at an example to demonstrate how a stateless bean works.
3.1. Creating the Stateless Bean
First, let’s create the StatelessEJB bean. We use the @Stateless annotation to mark the bean as stateless:
@Stateless
public class StatelessEJB {
public String name;
}
Then we create the first client of the above stateless bean, called EJBClient1:
public class EJBClient1 {
@EJB
public StatelessEJB statelessEJB;
}
We then declare another client, named EJBClient2, that accesses the same stateless bean:
public class EJBClient2 {
@EJB
public StatelessEJB statelessEJB;
}
3.2. Testing the Stateless Bean
To test the statelessness of the EJB, we can use the two clients we declared above in the following way:
@RunWith(Arquillian.class)
public class StatelessEJBTest {
@Inject
private EJBClient1 ejbClient1;
@Inject
private EJBClient2 ejbClient2;
@Test
public void givenOneStatelessBean_whenStateIsSetInOneBean
_secondBeanShouldHaveSameState() {
ejbClient1.statelessEJB.name = "Client 1";
assertEquals("Client 1", ejbClient1.statelessEJB.name);
assertEquals("Client 1", ejbClient2.statelessEJB.name);
}
@Test
public void givenOneStatelessBean_whenStateIsSetInBothBeans
_secondBeanShouldHaveSecondBeanState() {
ejbClient1.statelessEJB.name = "Client 1";
ejbClient2.statelessEJB.name = "Client 2";
assertEquals("Client 2", ejbClient2.statelessEJB.name);
}
// Arquillian setup code removed for brevity
}
We start by injecting the two EBJ clients into the unit test.
Then, in the first test method, we set the name variable in the EJB that was injected into EJBClient1 to the value Client 1. Now, when we compare the value of the name variable in both clients, we should see that the value is equal. This shows that state is not preserved in stateless beans.
Let’s demonstrate that this is true in a different way. In the second test method, we see that once we set the name variable in the second client it ‘overwrites’ whatever value was given to it via ejbClient1.
4. Stateful Beans
Stateful session beans maintain state both within and between transactions. That is why each stateful session bean is associated with a specific client. Containers can save and retrieve the state of a bean automatically while managing instance pools of stateful session beans.
4.1. Creating the Stateful Bean
A stateful session bean is marked with the @Stateful annotation. The code for the stateful bean is as follows:
@Stateful
public class StatefulEJB {
public String name;
}
The first local client for our stateful bean is written as follows:
public class EJBClient1 {
@EJB
public StatefulEJB statefulEJB;
}
A second client called EJBClient2 is also created just like the EJBClient1:
public class EJBClient2 {
@EJB
public StatefulEJB statefulEJB;
}
4.2. Testing the Stateful Bean
The functionality of the stateful bean is tested in the EJBStatefulBeanTest unit test in the following way:
@RunWith(Arquillian.class)
public class StatefulEJBTest {
@Inject
private EJBClient1 ejbClient1;
@Inject
private EJBClient2 ejbClient2;
@Test
public void givenOneStatefulBean_whenTwoClientsSetValueOnBean
_thenClientStateIsMaintained() {
ejbClient1.statefulEJB.name = "Client 1";
ejbClient2.statefulEJB.name = "Client 2";
assertNotEquals(ejbClient1.statefulEJB.name, ejbClient2.statefulEJB.name);
assertEquals("Client 1", ejbClient1.statefulEJB.name);
assertEquals("Client 2", ejbClient2.statefulEJB.name);
}
// Arquillian setup code removed for brevity
}
As before the two EJB clients are injected into the unit test. In the test method, we can see that the value of the name variable is set via the ejbClient1 client and is maintained even though the value of name set via the ejbClient2 is different. This demonstrates that the state of the EJB is maintained.
5. Stateless vs. Stateful Session Bean
Now let’s have a look at the major difference between the two types of session beans.
5.1. Stateless Beans
- Stateless session beans maintain no state with the client. For this reason, they can be used to create a pool of objects which interact with multiple clients
- Since stateless beans don’t have any state per client, they are better performance wise
- They can handle multiple requests from multiple clients in parallel and
- Can be used for retrieving objects from databases
5.2. Stateful Beans
- Stateful session beans can maintain state with multiple clients, and the task is not shared among clients
- The state lasts for the duration of the session. After the session is destroyed, the state is not retained
- The container can serialize and store the state as a stale state for future use. This is done to save application server resources and to support bean failures and is passivation
- Can be used to solve producer-consumer type problems
6. Conclusion
So we have created two types of session beans and corresponding clients to invoke the methods from the beans. The project demonstrates the behavior of the two main types of session beans.
As always, the source code for the article is available on GitHub.