Using a Model Facade

Status: In Early Access
Sean Brydon

Problem Description

Java EE 5 applications can use Java Persistence APIs to create domain models. When designing code that will access your entities in the model tier, the calling client code, such as a Servlet, a JSP page or a JSF managed bean, will access the entity APIs.  With Java Persistence entities, the clients may get exposed to transactions APIs, EntityManager APIs and other features of the persistence APIs which are necessary to access the entities in the model. Also, the client code may need to interact with several entities, and each entity will have a different API and maybe different requirements for transactions and entity manager operations. As your application gets larger, the code can have a lot of APIs for clients of the model to use and this can get difficult to manage as the client code can become tightly coupled to the entity model.

Note, this topic has two related documents which discuss different strategies for using a facade.
As your application grows, you might need to repeat the same code for access to multiple Java Persistence Objects. Often this results in copying similar data access logic into each servlet or managed bean that needs to access the entities. Not only is this repetitive code difficult to manage, but it tightly couples the code to the entity model.

image of code without a model facade


The Facade pattern defines a higher level class that encapsulates and centralizes the interactions between Java Persistence clients and the model entities and operations of the Java Persistence APIs. It provides a single interface for operations on a set of entities. Using the Facade pattern can make the code in your Java Persistence clients cleaner. A web component using a Facade does not have to be aware of all the details of the APIs for each entity and does not have to be aware of any persistence mechanisms being used when accessing the entity managers or transaction managers. Introducing a facade between the calling clients and the entities in the model tier makes the code more loosely-coupled and easier to maintain.

image of code after using a model facade

The image above shows the code after applying the model facade pattern. The Web components such as a JSF Managed Bean or a Servlet will use the Facade handle operations on the Java Persistence Objects. The Facade will contain all the code to handle transaction and persistence APIs.

Solution

As code example 1 shows, the code with a facade is cleaner. Without using a facade, the client of the entities needs to know details about the entity and you might have similar code cut-and-pasted in other places whenever access to the entity was needed. The code after introducing a facade hides many of the details of the entities in the model tier.

Code Before Code After Introducing a Facade 
public class MyWebClient ... {
  
  ...


  public void doGet(HttpServletRequest request,
            HttpServletResponse response)
{
...
//processing a web request to
//add a new Item to the database
if (selectedURL.equals("additem.do")) {
  String desc = request.getParameter("item_desc");
  String name = request.getParameter("item_name");
  ...
  Item item = new Item();
  item.setName(name);
  item.setDescription(desc);

 
//now access entities in model tier
  EntityManager em =
          emf.createEntityManager();
    try{
      utx.begin();
      em.joinTransaction();
      em.persist(item);
      utx.commit();
    } catch(Exception exe){
            System.out.println("Error persisting item: "+exe);
        try {
            utx.rollback();
        } catch (Exception e) {}
    } finally {
        em.close();
    }
  }
...

public class MyWebClient { ...

...

  public void doGet(HttpServletRequest request,
            HttpServletResponse response)
{
...
//processing a web request to
//add a new Item to the database
if (selectedURL.equals("additem.do")) {
  String desc = request.getParameter("item_desc");
  String name = request.getParameter("item_name");
  ...
  Item item = new Item();
  item.setName(name);
  item.setDescription(desc);
  //now access entities in model tier
  MyModelFacade myfacade = new 
MyModelFacade(); 
  myfacade.addItem(item);
  }
Code Example 1: Refactoring the Client Calling Code by Introducing a Facade to Access the Entities in the Model Tier

When designing a facade, here are some design choices to consider: Lets consider some of the choices we made in the facades we used. In our example applications we show both a web and a session bean facade. These examples will be discussed in more details below.

 Strategy 1: Using a Web Component Facade 

One strategy to implement a facade is to use a Web component as the facade class. This strategy is useful if you want to have a web-only architecture and do not want to use an EJB container or if you just want to keep the facade in the web container.  If your application is using a web-only architecture and has the web components accessing the entities then using a facade can help clean up the code.

For more a full description of this strategy, see Using a Web Component as a Model Facade.

Strategy 2: Using a Session Bean Facade

An alternative strategy for implementing a facade is to use a Session Bean as the facade. In this design you will need to use the EJB container as it offers support for Session Beans. One advantage of this strategy is that session beans can take advantage of container services such as container-managed transactions. So your code does not need to include any extra code to manage the transactions using JTA APIs.

For more a full description of this strategy, see Using a Session Bean as a Model Facade.

References

Here are some references to consider:

Java BluePrints | Sun Microsystems © 2007 Sun Microsystems Inc. All rights reserved. Use is subject to license terms.