If you’re working with Spring, check out "REST With Spring":

>> CHECK OUT THE COURSE

1. Introduction

Enterprise Session Beans can be broadly classified into:

  1. Stateless Session Beans
  2. 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>
The latest dependency can be found in the Maven Repository. This dependency ensures that all Java EE 7 APIs are available during compile time. The provided scope ensures that once deployed; the dependency will be provided by the container where it has been deployed.

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.

The new Certification Class of "REST With Spring" is finally out:

>> CHECK OUT THE COURSE

Sort by:   newest | oldest | most voted
Xavier
Guest

Are you sure it is a good idea to use public fields on session beans? With all the layers of proxies/interceptors applied on each bean, there’s a big chance you are setting the name on the proxy instead of the bean itself.

Just try implementing a method on your stateful bean which prints its name and see the result.

Pritam Banerjee
Guest

Hi Xavier!

You are absolutely right, we should not use ideally public fields in beans. But since this is just an example and we wanted to give the simplest example to demonstrate the functionality of a bean we used public fields. Ideally there should be a private field with setters and getters. And those should control the access of the fields.

wpDiscuz