Overview of Container-Managed Persistence

The EJB specification provides for two different ways of implementing Entity beans. The first approach, covered yesterday, is for the bean provider to embed the persistence logic within the bean itself—hence the name bean-managed persistence or BMP. The second is for the container vendor to provide that logic, either generated by the EJB container vendor's deployment tools or as part of the EJB container itself. Entity beans built this way are called CMP Entity beans.

NOTE

CMP Entity beans have always been part of the EJB specification, first in EJB 1.0 and then with some minor refinements in EJB 1.1. There were substantial changes to CMP Entity beans in EJB 2—so substantial, in fact, that CMP 1.1 Entity beans are not forward compatible with EJB 2.

To deal with this, the EJB specification actually provides two different ways to write CMP Entity beans. The first is the legacy 1.1 approach; beans that are written this way indicate it using an entry in their deployment descriptor. The second is using the far more powerful approach introduced in EJB 2.

Today, you will be learning only about the EJB 2 approach.


The “anatomy” of CMP Entity beans is very much the same as BMP Entity beans:

  • They both have a local-home (or remote-home) interface that defines the create methods, the finder methods, optional home methods, and a remove method.

  • They both have a local (or remote) interface that defines the business methods of the bean.

  • Obviously, they both have a bean class itself that implements methods corresponding to the previously mentioned interfaces, and also implements the lifecycle methods inherited from javax.ejb.EntityBean.

  • Finally, if the primary key is not a standard Java class such as String or Integer, both BMP and CMP beans have a primary key class.

However, responsibilities of the CMP Entity bean in lifecycle methods are different, because there is no longer any requirement to persist the bean's state; persistence is now the responsibility of the EJB container. There are also changes in the interactions between the container and the bean, as you will see.

Another difference for CMP Entity beans is there is no longer any need to implement the finder methods in the bean. Under BMP, the bean provider writes the appropriate finder methods; under CMP, the container will do this work. However, the bean provider must specify the query to obtain the correct data from the data store using EJB Query Language (EJB QL). EJB QL shares many similarities with ANSI SQL 92, so if you are familiar with SQL you should not have too many difficulties picking it up.

Entity beans, like tables in relational databases, have relationships. You saw this yesterday with the Job bean, which had relationships with the Skill, Location, and Customer beans. Under BMP, the bean provider must write the code that maintains all of these relationships explicitly. If CMP is used, these relationships can be defined declaratively using container-managed relationships, or CMR.

Relationships between Entity beans are intrinsically fine-grained. Using the Agency case study as an example, a many-to-many relationship between Job and Skill (indicating which skills are needed for which job) would involve many (job, skill) tuples stored in the JobSkill table. Because the performance cost of maintaining a fine-grained relationship across the network would be too severe, the EJB specification requires that container-manager relationships between Entity beans are defined only through local interfaces. Indeed, one of the primary reasons for the introduction of local interfaces in the EJB specification was to make CMR feasible.

N-tier Architecture (Revisited Again) and CMP Fields

CMP has an impact on the n-tier architecture that you have seen on previous days. Figure 7.1 updates a figure that you saw yesterday for CMP Entity beans.

Figure 7.1. CMP Entity beans are split into two components.


There are still four tiers to the architecture—namely, the interface, application, domain, and persistence layers. However, with CMP, the Entity beans are split into two components. The first component is provided by you, the bean provider, and comprises

  • The bean's local-home and local interfaces

  • An implementation of the business methods

  • Abstract definitions of the accessor methods for the bean's properties (but no implementation, as this is provided by the container)

The second component is the concrete implementation of the CMP bean supplied by the EJB container provider from declarative information provided by you. This component has dependencies on both the bean and the persistence layer. The first dependency occurs because the concrete implementation uses the bean provider's abstract bean class as its superclass; in other words, it extends from the CMP bean. The second dependency is because the implementation of the bean performs appropriate data store calls.

You may recognize this design as an instance of the Template design pattern. The abstract CMP bean is a template, defining certain mandatory “hook” methods—specifically, the property accessor methods. As part of the deployment process the EJB container will generate a concrete class implementing the bean property accessor methods using information supplied in the deployment descriptor.

Listing 7.1 shows a CMP version of the Job Entity bean. This bean defines a pair of accessor methods (the getter and setter methods) for each of its properties—ref, customer, description, location, and skills.

Listing 7.1. The Full Text of CMP Entity Bean JobBean.java
Package data;

import java.rmi.*;
import java.sql.*;
import java.util.*;
import javax.ejb.*;
import javax.naming.*;
import javax.sql.*;

public abstract class JobBean implements EntityBean
{
    // CMP fields
    public abstract String getRef ();
    public abstract void setRef (String ref);
    public abstract String getCustomer ();
    public abstract void setCustomer (String customer);
    public abstract String getDescription ();
    public abstract void setDescription(String description);

    // CMR fields
    public abstract LocationLocal getLocation ();
    public abstract void setLocation(LocationLocal location);
    public abstract Collection getSkills();
    public abstract void setSkills(Collection skills);

    // EJB methods start here

    public void ejbPostCreate (String ref, String customer) {}
    public JobPK ejbCreate (String ref, String customer)
                            throws CreateException {
        setRef(ref);
        setCustomer(customer);
        setDescription("");
        return new JobPK(ref,customer);
    }

    public void ejbHomeDeleteByCustomer(String customer)
                 throws FinderException, RemoveException {
        Collection jobs = ((JobLocalHome)ctx.getEJBLocalHome()).findByCustomer(customer);
        for (Iterator iter = jobs.iterator(); iter.hasNext(); ) {
            JobLocal job = (JobLocal)iter.next();
            iter.remove();
            job.remove();
        }

    }

    public void ejbLoad() {}
    public void ejbStore() {}
    public void ejbPassivate() {}
    public void ejbActivate() {}
    public void ejbRemove() {}

    private EntityContext ctx;

    public void setEntityContext(EntityContext ctx) {
        this.ctx = ctx;
    }

    public void unsetEntityContext() {
        this.ctx = null;
    }
}

Unlike BMP you do not declare the instance variables that correspond to the properties of the Entity bean, so you must use the getter and setter methods for accessing the data. This is reflected in the revised implementation of the ejbCreate() method which uses the templated setter methods to store property values for the newly created EJB.

NOTE

This JavaBean naming scheme means that CMP fields must not start with a capital letter. Thus, customer and even cUSTOMER are valid names, but CUSTOMER would not be. This is because the methods capitalize the CMP fields, and a capital letter cannot be capitalized!


One immediate advantage of using CMP Entity beans is that it gives the EJB container (through the concrete bean implementation) much more control over populating the bean's state, without compromising good OO principles. For example, it is up to the EJB container whether it chooses to obtain all of the bean's state when the bean is activated or created (eager loading), or whether it chooses to fetch the bean's state from the persistent data store as and when needed (lazy loading).

Another advantage of CMP is that the EJB container only need persist the bean's state to the data store when the bean's state has changed. If a read-only accessor method (a “getter” method) is called, there would be no change in state, and so the concrete implementation does not need to perform an unnecessary update to the data store. Taking this one stage further, when the bean's state is changed, the EJB container only needs to update those fields that have changed and can ignore fields that have not changed. One final advantage worth mentioning is that CMP simplifies the implementation of some value-add services, such as optimistic locking.

You can see from Listing 7.1 that most of the EJB lifecycle methods have nothing to do; this reflects the different lifecycle requirements for CMP Entity beans.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
13.59.193.151