The Session Façade design pattern is popular for developing enterprise applications based on J2EE (Java 2 Platform, Enterprise Edition). It not only enforces reusable application architecture design but also provides many advantages, including reduced network overhead, centralized security management and transaction control, coarse-grained abstraction of business data and service objects, and reduced coupling between clients and business objects.

The Session Façade design pattern is a must-have to successfully develop software with J2EE. It is difficult to decide how to most effectively use Session Façade in a specific project. There are many factors to consider: project business requirements, project scope, and complexity, just to name a few. In most situations, developers use the Session Façade pattern with Value Object and other related design patterns, but I have found some limitations to this approach in several projects, especially when constructing large and complex systems.

Within this article, I will first provide an introduction to the Session Façade design pattern, the benefits it brings, and the pros and cons when using Session Façade with the Value Object pattern. Then I will present the alternate solution: Session Façade with XML.

Session Façade overview

The Session Façade design pattern uses an enterprise session bean as a façade, which abstracts the underlying business object interactions and provides a uniform, coarse-grained service access layer to clients.

In a distributed J2EE application, the client-tier application interacts with the server by exchanging data between itself and the EJB (Enterprise JavaBeans) tier. Due to the overhead of multiple network calls and poor concurrency, it can be a performance killer if the client-tier application directly invokes multiple fine-grained methods on session/entity EJB components (which I call business objects) in the J2EE application's EJB tier.

Consider a J2EE banking application, where a bank customer asks a bank teller to transfer money from his savings account to his checking account. In this scenario, the bank standalone client application must first validate the customer before withdrawing money from the savings account and depositing it into the checking account. The sequence diagram in Figure 1 shows the interaction between the client tier and the EJB tier.

Figure 1. Interaction between client and EJB tiers

This approach features two main drawbacks. First, it doesn't scale. The client application must make remote calls to each enterprise bean. There are six network calls in all, as shown in Figure 1's sequence diagram.

The second drawback: This approach has poor concurrency. The client application must wrap the calls to SavingAccount and CheckingAccount within one transaction to maintain the customer's account in a consistent state. The transaction will be stretched longer due to network overhead, and as a result, this approach inevitably increases the chances of deadlock and reduces concurrency.

The solution to our design dilemma is to add a higher-level abstraction layer between the client-tier application and the EJB tier using the Session Façade design pattern, which is implemented as a session bean. The sequence diagram in Figure 2 shows the interactions between the client and EJB tiers after a banking Session Façade session bean is added.

Figure 2. Sequence diagram using Session Façade

In our example, Session Façade reduces the number of networks from six to one. Plus access to each entity bean is now through its local interface, not through its remote interface. This minimizes the network overhead. The Session Façade session bean encapsulates all logic for the business domain and centralizes the transactions on the server. This results in a high concurrency.

In our banking application, we use a method call transfer() with parameters to transfer data from the client tier to the EJB tier through the Session Façade. This approach will soon get out of hand for sophisticated business domain applications, which most likely will handle large amounts of parameters. Additionally, we should not use multiple fine-grained calls with the Session Façade to transfer bulk data due to network overhead, which is one of the reasons why we introduced the Session Façade pattern into our example in the first place. Instead of transfer(), you can use the Value Object design pattern for exchanging data between the client and EJB tiers through the Session Façade session beans. A value object is a serializable Java class that encapsulates business data. This code snippet shows the value object AccountTransferValueObject, which can replace transfer() in our banking application example:

 public class AccountTransferValueObject implements java.io.Serializable {
   private String customerPK;
   private String fromAccountPK;
   private String toAccountPK;
   private float  amount;
   ...
   public String getCustomerPK(){
      return customerPK;
   }
   public String getFromAccountPK(){
      return fromAccountPK;
   }
   public String getToAccountPK(){
      return toAccountPK;
   }
   public float  getTransferAmount(){
      return amount;
   }
   
   public void setCustomerPK(String customerPK){
      this.customerPK = customerPK;
   }
   
   public void setFromAccountPK(String fromAccountPK){
      this.fromAccountPK = fromAccountPK;
   }
   
   public void setToAccountPK(String toAccountPK){
      this.toAccountPK = toAccountPK;
   }
   
   public void  setTransferAmount(float amount){
      this.amount = amount;
   }
}

When the client tier sends data to the EJB tier for processing, the client tier creates a value object to wrap all the necessary information and sends the object to the EJB tier through a Session Façade interface. Likewise, when the client tier receives data from the EJB tier, the EJB tier creates value objects to wrap all information collected from the entity beans, and sends the objects to the client tier through a Session Façade interface.

The challenges of using Session Façade with Value Object

For well-understood and simple business domains you can easily define value objects. For sophisticated business domains, due to their potentially large number of value objects and customization requirements, this task grows complicated, even if the analysis and design teams thoroughly analyzed the business domain.

Using the Session Façade pattern with Value Object also features the following challenges:

  • When the client tier receives bulk data from the EJB tier, the client receives either value objects or an exception, but not both. In real-world applications, you sometimes want to retrieve both value objects and business exceptions from the EJB tier. From a performance perspective, it is expensive to throw an application business exception every time a business rule validation fails on the EJB tier. Whenever an exception is thrown, because of the newly created business exception object, the JVM must fix the call stack. Exceptions should be used for error conditions only.
  • The coupling and dependency between the client and EJB tiers is only reduced, not eliminated, thus parallel development of the different application layers cannot be fully achieved. Without the Session Façade layer, clients must directly invoke the fine-grained methods on session/entity EJB components (business objects). If business objects need changing in the future, then you must also change the clients. By introducing the Session Façade layer, you might be able to avoid changing the clients if business objects change. As a result, the coupling and dependency between the client and EJB tiers is reduced. But the client tier is still coupled with the EJB tier through value objects. Whenever the value objects change, you usually need to recompile the client tier classes. Since value objects tend to change often, they might create a terrible bottleneck between the client and EJB tiers, especially for big projects that have large numbers of value objects.
  • Using the Session Façade pattern with Value Object offers no implicit audit-trail capability. As enterprise applications grow more and more complicated, different applications need to interact with each other. With audit-trail capability built in, while application-processing requests travel through different application tiers or even different enterprise applications, system activities can be properly tracked and audited.

XML to the rescue

As an alternative to value objects, we'll use XML data streams to exchange arbitrary data sets between tiers through the Session Façade session beans. This simplified XML Schema illustrated in Figure 3 defines the structure, content, and semantics of the XML documents used to exchange data sets between the client and EJB tiers.

Figure 3. XML Schema object view. Click on thumbnail to view full-size image.

The client tier uses the input node to flexibly package request data that will be sent to the EJB tier for processing. The input node can contain zero or more fieldset nodes; a fieldset node can contain one or more field nodes and zero or more dataset nodes. A field node can have one or more value elements, which contain the actual value for each field. The field node might contain a data array. The nodes fieldset, field, and dataset all have a required name attribute.

The EJB tier uses the output node to send a response back to the client tier. The output node is also flexible. It can send both flat tabular data and hierarchical data back. The main data structure within the output node is the dataset node. output can contain zero or more dataset nodes, which in turn, can have zero or more row nodes and zero or more nested dataset nodes.

The client and EJB tiers exchange information about application business domain-related errors and possible system errors in the errors node. The errors node can contain zero or more error nodes; each error node has a source element, an errorcode element, and a description element. In addition, the error node has a category attribute, which can be one of two possible values: system and business.

The audits node logs the system activities on different tiers or different applications. The audits node can have zero or more audit nodes; and each audit node has both a timestamp and description element.

For the text view of the XML data stream schema, please download the source code. The following code shows a simple XML example using this schema:

<sessionfacade xmlns="sessionfacade" 
               xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"
               xsi:schemaLocation="sessionfacade sessionfacade.xsd">
   <input>
      <fieldset name="trade">
         <field name="action"><value>buy</value></field>
         <field name="customer"><value>Jason Cai</value></field>
         <field name="stocksymbol"><value>JAVA</value></field>
         <field name="shares"><value>10000</value></field>
      </fieldset>
   </input>
   <output>
      <dataset name="trade">
         <row>
            <field name="numbertraded"><value>0</value></field>
            <field name="action"><value>buy</value></field>
            <field name="price"><value>0.00</value></field>
         </row>
      </dataset>
   </output>
   <errors>
      <error category="business">
         <source>TradeBean</source>
         <errorcode>10001</errorcode>
         <description>Stock symbol Java does not exist</description>
      </error>
   </errors>
   <audits/>
</sessionfacade>

Using XML data stream has the following benefits:

  • The client tier will be able to retrieve both multiple data sets and business validation exceptions from the EJB tier with just one remote call.
  • The XML data stream eliminates the coupling and dependency between the client and EJB tiers, and achieves parallel development. Additionally, using XML results in less custom development. A validating XML parser can use a supplied schema to automatically check an XML data stream's syntax and enforce business rules.

  • The audit-trail capability is built-in.
  • XML data streams are self documenting. XML tags' textual nature and the inclusion of a well-defined schema greatly reduce guesswork during application development.
  • XML allows companies to create open and standardized interfaces for existing systems.

The implementation

Our Session Façade with XML implementation, shown in Figure 4, defines three Java interfaces and abstract classes as its core classes.

Figure 4. Session Façade class diagram

ISessionFacade interface, as shown in the code snippet below, defines two process() methods with different signatures. One method takes a string representation of an XML input data stream as its input parameter and returns a string representation of an XML output data stream. The other takes an XML DOM (Document Object Model) document as its input parameter and returns an XML DOM document. Both a Session Façade session bean's remote interface and its bean class must implement the ISessionFacade interface: