Business Tier Design Considerations
- Business Tier Design Considerations
- Business and Integration Tiers Bad Practices
Topics in This Chapter
-
Business Tier Design Considerations
-
Business and Integration Tiers Bad Practices
Business Tier Design Considerations
When you apply the business tier and integration tier patterns in this book, you'll need to know about related design issues, which we cover in this chapter. These issues cover a variety of topics, and can affect many aspects of a system.
The discussions in this chapter simply describe each issue as a design issue that you should consider when implementing systems based on the J2EE pattern catalog.
Using Session Beans
Session beans are distributed business components with the following characteristics, per the EJB specification:
-
A session bean is dedicated to a single client or user.
-
A session bean lives only for the duration of the client's session.
-
A session bean does not survive container crashes.
-
A session bean is not a persistent object.
-
A session bean can time out.
-
A session bean can be transaction aware.
-
A session bean can be used to model stateful or stateless conversations between the client and the business tier-components.
In this section, we use the term workflow in the context of EJB to represent the logic associated with the enterprise beans communication. For example, workflow encompasses how session bean A calls session bean B, then entity bean C.
Session Bean—Stateless Versus Stateful
Session beans come in two flavors—stateless and stateful. A stateless session bean does not hold any conversational state. Hence, once a client's method invocation on a stateless session beans is completed, the container is free to reuse that session bean instance for another client. This allows the container to maintain a pool of session beans and to reuse session beans among multiple clients. The container pools stateless session beans so that it can reuse them more efficiently by sharing them with multiple clients. The container returns a stateless session bean to the pool after the client completes its invocation. The container may allocate a different instance from the pool to subsequent client invocations.
A stateful session bean holds conversational state. A stateful session bean may be pooled, but since the session bean is holding state on behalf of a client, the bean cannot simultaneously be shared with and handle requests from another client.
The container does not pool stateful session beans in the same manner as it pools stateless session beans because stateful session beans hold client session state. Stateful session beans are allocated to a client and remain allocated to the client as long as the client session is active. Thus, stateful session beans need more resource overhead than stateless session beans, for the added advantage of maintaining conversational state.
Many designers believe that using stateless session beans is a more viable session bean design strategy for scalable systems. This belief stems from building distributed object systems with older technologies, because without an inherent infrastructure to manage component life cycle, such systems rapidly lost scalability characteristics as resource demands increased. Scalability loss was due to the lack of component life cycle, causing the service to continue to consume resources as the number of clients and objects increased.
An EJB container manages the life cycle of enterprise beans and is responsible for monitoring system resources to best manage enterprise bean instances. The container manages a pool of enterprise beans and brings enterprise beans in and out of memory (called activation and passivation, respectively) to optimize invocation and resource consumption.
Scalability problems are typically due to the misapplication of stateful and stateless session beans. The choice of using stateful or stateless session beans must depend upon the business process being implemented. A business process that needs only one method call to complete the service is a non-conversational business process. Such processes are suitably implemented using a stateless session bean. A business process that needs multiple method calls to complete the service is a conversational business process. It is suitably implemented using a stateful session bean.
However, some designers choose stateless session beans, hoping to increase scalability, and they may wrongly decide to model all business processes as stateless session beans. When using stateless session beans for conversational business processes, every method invocation requires the state to be passed by the client to the bean, reconstructed at the business tier, or retrieved from a persistent store. These techniques could result in reduced scalability due to the associated overheads in network traffic, reconstruction time, or access time respectively.
Storing State on the Business Tier
Some design considerations for storing state on the Web server are discussed in “Session State in the Presentation Tier” on page 21. Here we continue that discussion to explore when it is appropriate to store state in a stateful session bean instead of in an HttpSession.
One of the considerations is to determine what types of clients access the business services in your system. If the architecture is solely a Web-based application, where all the clients come through a Web server either via a servlet or a JSP, then conversational state may be maintained in an HttpSession in the web tier. This scenario is shown in Figure 3.1.
Figure 3.1. Storing State in HttpSession
On the other hand, if your application supports various types of clients, including Web clients, Java applications, other applications, and even other enterprise beans, then conversational state can be maintained in the EJB layer using stateful session beans. This is shown in Figure 3.2.
Figure 3.2. Storing State in Session Beans
We have presented some basic discussion on the subject of state management here and in the previous chapter (see “Session State on the Client” on page 20). A full-scale discussion is outside the scope of this book, since the problem is multi-dimensional and depends very much on the deployment environment, including:
-
Hardware
-
Traffic management
-
Clustering of Web container
-
Clustering of EJB container
-
Server affinity
-
Session replication
-
Session persistence
We touch on this issue because it is one that should be considered during development and deployment.
Using Entity Beans
Using entity beans appropriately is a question of design heuristics, experience, need, and technology. Entity beans are best suited as coarse-grained business components. Entity beans are distributed objects and have the following characteristics, per the EJB specification:
-
Entity beans provide an object view of persistent data.
-
Entity beans are transactional.
-
Entity beans are multiuser.
-
Entity beans are long-lived.
-
Entity beans survive container crashes. Such crashes are typically transparent to the clients.
Summarizing this definition, the appropriate use of an entity bean is as a distributed, shared, transactional, and persistent object. In addition, EJB containers provide other infrastructure necessary to support such system qualities as scalability, security, performance, clustering, and so forth. All together, this makes for a very reliable and robust platform to implement and deploy applications with distributed business components.
Entity Bean Primary Keys
Entity beans are uniquely identified by their primary keys. A primary key can be a simple key, made up of a single attribute, or it can be a composite key, made up of a group of attributes from the entity bean. For entity beans with a single-field primary key, where the primary key is a primitive type, it is possible to implement the entity bean without defining an explicit primary key class. The deployer can specify the primary key field in the deployment descriptor for the entity bean. However, when the primary key is a composite key, a separate class for the primary key must be specified. This class must be a simple Java class that implements the serializable interface with the attributes that define the composite key for the entity bean. The attribute names and types in the primary key class must match those in the entity bean, and also must be declared public in both the bean implementation class and primary key class.
As a suggested best practice, the primary key class must implement the optional java.lang.Object methods, such as equals and hashCode.
-
Override the equals() method to properly evaluate the equality of two primary keys by comparing values for each part of the composite key.
-
Override the Object.hashCode() method to return a unique number representing the hash code for the primary key instance. Ensure that the hash code is indeed unique when you use your primary key attribute values to compute the hash code.
Business Logic in Entity Beans
A common question in entity bean design is what kind of business logic it should contain. Some designers feel that entity beans should contain only persistence logic and simple methods to get and set data values. They feel that entity beans should not contain business logic, which is often misunderstood to mean that only code related to getting and setting data must be included in the entity bean.
Business logic generally includes any logic associated with providing some service. For this discussion, consider business logic to include all logic related to processing, workflow, business rules, data, and so forth. The following is a list of sample questions to explore the possible results of adding business logic into an entity:
-
Will the business logic introduce entity-entity relationships?
-
Will the entity bean become responsible for managing workflow of user interaction?
-
Will the entity bean take on the responsibilities that should belong in some other business component?
A “yes” answer to any of these questions helps identify whether introducing business logic into the entity bean can have an adverse impact, especially if you use remote entity beans. It is desirable to investigate the design to avoid inter-entity-bean dependencies as much as possible, since such dependences create overheads that may impede overall application performance.
In general, the entity bean should contain business logic that is self-contained to manage its data and its dependent objects' data. Thus, it may be necessary to identify, extract, and move business logic that introduces entity-bean-to-entity-bean interaction from the entity bean into a session bean by applying the Session Façade pattern. The Composite Entity (391) pattern and some of the refactorings discuss the issues related to entity bean design.
If any workflow associated with multiple entity beans is identified, then you can implement the workflow in a session bean instead of in an entity bean. Use a Session Façade (341) or Application Service (357).
-
See “Merge Session Beans” on page 96.
-
See “Reduce Inter-Entity Bean Communication” on page 98.
-
See “Move Business Logic to Session” on page 100.
-
See Session Façade (341)
-
See Business Object (374)
-
See Composite Entity (391)
-
See Application Service (357)
For bean-managed persistence in entity beans, data access code is best implemented outside entity beans.
-
See “Separate Data Access Code” on page 102.
-
See Data Access Object (462).
Caching Enterprise Bean Remote References and Handles
When clients use an enterprise bean, they might need to cache some reference to an enterprise bean for future use. You will encounter this when using business delegates (see Business Delegate (302)), where a delegate connects to a session bean and invokes the necessary business methods on the bean on behalf of the client.
When the client uses the business delegate for the first time, the delegate needs to perform a lookup using the EJB Home object to obtain a remote reference to the session bean. For subsequent requests, the business delegate can avoid lookups by caching a remote reference or its handle as necessary.
The EJB Home handle can also be cached to avoid an additional Java Naming and Directory Interface (JNDI) lookup for the enterprise bean home. For more details on using an EJB Handle or the EJB Home Handle, please refer to the current EJB specification.