Distributed Objects   «Prev  Next»

Lesson 5 Stateless and Stateful Session Beans
Objective Distinguish stateless and stateful session beans in Jakarta Enterprise Beans.

Stateless and Stateful Session Beans in Jakarta EE 11

Session Beans in Jakarta Enterprise Beans

Session beans are managed business components provided by Jakarta Enterprise Beans. In Jakarta EE 11, the key difference between a stateless session bean and a stateful session bean is not how a client obtains a remote object or communicates through legacy middleware. The important distinction is whether the component retains client-specific conversational state between method invocations.

A stateless session bean performs operations that do not depend on information retained from a previous call by the same client. The container can therefore maintain a pool of stateless bean instances and route incoming calls to available instances. A stateful session bean, in contrast, represents a conversation with a particular client and can retain information in instance fields from one method invocation to the next.

Both types run in a managed environment. The Jakarta EE runtime can provide dependency injection, declarative transactions, security, interceptors, persistence integration, lifecycle services, and other enterprise facilities. The choice between stateless and stateful should therefore be based primarily on the application's state and conversation requirements.


Jakarta EE 11 runtime showing client applications reaching CDI managed beans and Jakarta Enterprise Beans through HTTPS, REST, or Servlet endpoints
Jakarta EE 11 runtime showing client applications reaching CDI managed beans and Jakarta Enterprise Beans through HTTPS, REST, or Servlet endpoints.

Stateless Session Beans

A stateless session bean is declared with the @Stateless annotation. It is designed for operations that do not require the bean to remember client-specific conversational information after a method invocation completes. Each request should contain, or provide access to, the information necessary to perform the requested operation.

This does not mean that a stateless bean can never have instance fields. An instance can use fields internally, and values may remain in those fields while the instance stays in the container's pool. Application code must not, however, depend on those values representing one client's state during a later invocation. A subsequent call from the same client may be handled by a different bean instance, while the original instance may later serve another client.

This property makes stateless beans well suited to service operations such as calculations, validation, order submission, database updates, payment orchestration, inventory checks, and other independent units of business logic. Because instances are reusable, the container can serve many clients with a managed pool rather than maintaining a dedicated component instance for every client conversation.

import jakarta.ejb.Stateless;
import java.math.BigDecimal;

@Stateless
public class TaxService {

    public BigDecimal calculateTax(Order order) {
        // Independent operation; no client-specific conversational state.
        return order.subtotal().multiply(new BigDecimal("0.07"));
    }
}

The supporting Order type is abbreviated here for teaching clarity. The important design feature is that calculateTax() can perform its work from the information supplied to the method. It does not depend on a value remembered from an earlier request by the same client.

Stateful Session Beans

A stateful session bean is declared with @Stateful. Unlike a stateless bean, a stateful bean preserves conversational state for a client across multiple business method calls. The container maintains the association between the client conversation and the stateful bean instance for the lifetime of that conversation.

A common use case is a multi-step workflow. For example, a checkout process may collect selected items during one method call, shipping information during another, and payment choices during another. The stateful component can retain temporary conversation data while the user progresses through the process.

import jakarta.ejb.Stateful;
import jakarta.ejb.StatefulTimeout;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Stateful
@StatefulTimeout(value = 20, unit = TimeUnit.MINUTES)
public class CheckoutConversation {

    private final List<String> itemIds = new ArrayList<>();

    public void addItem(String itemId) {
        itemIds.add(itemId);
    }
}

The @StatefulTimeout annotation allows the application to specify how long an idle stateful conversation may remain before the container is allowed to remove it. Stateful beans may also define an appropriate removal method with @Remove when the application has an explicit point at which the conversation finishes.

Because each active stateful conversation requires associated runtime state, stateful beans usually require more container resources than stateless beans. A Jakarta Enterprise Beans implementation may use passivation to move an eligible inactive stateful instance out of active memory and later activate it when needed. Passivation is a lifecycle optimization, not a durable storage system.

If information must survive application restarts, server failures, or the end of a user's conversation, that information should be stored in durable storage. Jakarta Persistence, a database, or another durable data service is appropriate for business records that must outlive the stateful bean.

Comparing Stateless and Stateful Beans

Characteristic Stateless Session Bean Stateful Session Bean
Client-specific conversational state Does not retain client-specific conversational state between method calls Retains conversational state for an associated client across method calls
Instance management Instances are reusable and commonly managed in a pool An instance is associated with a client conversation
Scalability Generally efficient for large numbers of independent client requests Consumes additional resources because conversational state must be retained
Lifecycle The container creates, pools, reuses, and removes instances The container manages creation, conversational association, timeout, removal, and possible passivation
Passivation Not used to preserve a client conversation Eligible beans may be passivated and later activated by the container
Typical use cases Validation, calculations, service operations, database updates, orchestration Multi-step workflows, configurators, temporary carts, and client-specific conversations
Transactions Can participate in Jakarta Transactions Can participate in Jakarta Transactions
Durable application data Store durable data through Jakarta Persistence or another durable store Conversational fields are not durable database persistence; durable data should be stored separately

Client Access and Dependency Injection

Older Enterprise JavaBeans architectures often described clients locating enterprise components through naming services and communicating through distributed-object technologies. That is not the normal architecture for a modern browser-based or HTTP service application.

A browser, mobile application, or external service commonly sends an HTTPS request to an application endpoint such as a Servlet or Jakarta RESTful Web Services resource. That managed endpoint can then invoke application services inside the Jakarta EE runtime. The internal service may be a CDI managed bean or a Jakarta Enterprise Bean, depending on the services and lifecycle semantics required by the application.

CDI dependency injection is the ordinary mechanism for wiring managed application components together. A CDI managed bean is not automatically a session bean. CDI and Jakarta Enterprise Beans are different component models, although Jakarta EE integrates them so that session beans can participate in the dependency injection environment.

Jakarta Enterprise Beans can expose a no-interface view, a local business interface, or a remote business interface where appropriate. A remote business interface is useful when remote enterprise-component access is genuinely required, but it should not be confused with the normal HTTP architecture used by web clients.

JNDI remains available as a naming and resource mechanism, particularly for configured resources and integration scenarios. It is not a requirement that every modern client locate a session bean through JNDI before using an application.

Transactions, Persistence, and Durable State

Both stateless and stateful session beans can participate in declarative transaction management. Jakarta Transactions defines the transaction model used by Jakarta EE components. A business method can execute within a transaction boundary managed by the runtime, allowing multiple related database operations to succeed or roll back as a unit.

Jakarta Persistence provides the object-relational persistence model used for durable entity data. A session bean may invoke persistence operations inside a transaction while the persistence context tracks the affected entities. This separates temporary conversational state from durable business state.

For example, a stateful checkout component might temporarily retain selected product identifiers while a customer completes several steps. Once the order is confirmed, an application service can create persistent order and order item entities within a transaction. The stateful component's temporary list is part of the conversation; the database records represent the durable business result.

The same principle applies to stateless components. Stateless does not mean that an operation cannot update stored information. It means that the bean itself does not rely on client-specific conversational state between calls. A stateless service can read and modify large amounts of persistent shared data while still remaining stateless from the client's perspective.

Singleton Session Beans

Jakarta Enterprise Beans also defines @Singleton as a third session-bean type. A singleton session bean represents one shared component instance for an application and can be useful for application-wide coordination or shared managed state. It is different from a stateful session bean because its state is shared at the application level rather than being dedicated to one client conversation.

Choosing the Right Session Bean Type

Choose a stateless session bean when each operation can be completed independently and later calls do not need client-specific information retained by the component. This design usually provides the simplest scaling model because the container can distribute calls among reusable pooled instances.

Choose a stateful session bean when the application genuinely has a server-side conversation whose intermediate state must survive across several calls from the same client. A stateful bean is particularly useful when that conversation has a clear beginning, a bounded lifetime, and a clear completion point.

Do not choose a stateful bean simply because an application stores data. Persistent customer records, orders, accounts, products, and other durable information belong in an appropriate persistent store. Stateful session beans are intended for conversational state, not as replacements for Jakarta Persistence or database storage.

Likewise, do not use Jakarta Enterprise Beans merely because an application needs dependency injection. CDI managed beans provide a general-purpose component model for application services. Jakarta Enterprise Beans are appropriate when their defined session-bean semantics and enterprise services provide a concrete benefit.

Summary

The essential distinction between stateless and stateful session beans is conversational state. A stateless session bean does not preserve client-specific conversational state between invocations, allowing its instances to be pooled and reused efficiently. A stateful session bean maintains an association with a client conversation and preserves temporary state across multiple calls.

Both component types can use Jakarta EE services including dependency injection, Jakarta Transactions, Jakarta Persistence integration, security, and interceptors. Durable business information should be stored using persistence technology rather than relying on stateful bean fields. Modern HTTP clients normally enter the application through HTTP endpoints, while CDI and Jakarta Enterprise Beans provide managed component models inside the Jakarta EE application.


SEMrush Software