Types of Entity Persistence

Entity beans have two types of persistence: bean-managed persistence (BMP) and container-managed persistence (CMP). These two types are based on who is responsible for entity bean persistence bean provider or EJB provider.

Bean-Managed Persistence

With bean-managed persistence, the entity bean code that you write contains the calls that access the database. The data access can be coded into the entity bean class or encapsulated in a data access object that is part of the entity bean. Figure 8.3 depicts how bean-managed persistence works with database access.

Figure 8.3. Bean-managed persistence contains the calls that access the database.


For example, as shown in the following snippet, the StudentEJB method ejbCreate contains the JBDC code to insert a student record into the students table:

public class StudentEJB implements EntityBean {

  private String studentId; // also the primary Key
  private String firstName;
  private String lastName;
  private String address;

  public String ejbCreate(String studentId, String firstName,
    String lastName, String address) throws CreateException
  {
    this.studentId = studentId;
    this.firstName = firstName;
    this.lastName = lastName;
    this.address = address;

    Connection con = null;
    PreparedStatement ps = null;

    try {
      con = getConnection();
      ps = con.prepareStatement("insert into students (student_id, "+
        " first_name, last_name, address) values (?, ?, ?, ?) ");
      ps.setString(1, studentId);
      ps.setString(1, firstName);
      ps.setString(1, lastName);
      ps.setString(1, address);

      if (ps.executeUpdate() != 1) {
        String error = "JDBC did not create any row";
        log(error);
        throw new CreateException (error);
      }

      return studentId;
    } catch (SQLException sqe) {
    ...
    } finally {
      cleanup(con, ps);
    }
  }
  ...
}

Although writing this code is an additional responsibility, as an EJB developer, you'll have more control over how the entity bean accesses a database.

You'll learn more about bean-managed persistence on Day 10, “Developing Bean-Managed Persistence Entity Beans.”

Container-Managed Persistence

If your bean has container-managed persistence (CMP), the EJB container uses a persistence manager and automatically generates the necessary database access calls. The code that you write for the entity bean does not include these calls. The persistence manager is responsible for persistence of the entity bean, including creating, loading, and removing the entity bean instance in the database.

Figure 8.4. The persistence manager is responsible for persistence of CMP.


For example, as shown in the following listing, the OrderEJB method ejbCreate does not contain any JBDC code to insert order records into the orders table:

public abstract class OrderEJB implements EntityBean {

       /* get and set methods for cmp fields */
        public abstract String getOrderId();
        public abstract void setOrderId(String id);

        public abstract java.sql.Timestamp getOrderDate();
        public abstract void setOrderDate(java.sql.Timestamp timestamp);

        public abstract String getStatus();
        public abstract void setStatus(String status);

        public abstract double getAmount();
        public abstract void setAmount(double amount);

       /* get and set methods for relationship fields */
        public abstract Collection getLineItems();
        public abstract void setLineItems(Collection lineItems);

        public abstract StudentLocal getStudent();
        public abstract void setStudent(StudentLocal student);

        public String ejbCreate(String orderId, StudentLocal student,
          String status,double amount) throws CreateException {
         setOrderId(orderId);
         setOrderDate(new java.sql.Timestamp(System.currentTimeMillis()));
         setStatus(status);
         setAmount(amount);

         return null;
        }

  ...
}

You might question how the EJB container is able to generate the database access code. The answer is that you specify the persistence fields, relationship fields, schema, and queries in the deployment descriptor. Based on this information, the container tools generate data access calls corresponding to the underlying database, at deployment time. We'll examine each of them in the following sections.

Persistent Fields

A persistent field is designed to represent and store a single unit of data. Collectively, these fields constitute the state of the bean. During deployment, the container typically maps the entity bean to a database table and maps the persistent fields to the table's columns. At runtime, the EJB container automatically synchronizes this state with the database.

An OrderEJB entity bean, for example, might have persistent fields such as orderId, orderDate, status, and amount. In container-managed persistence, these fields are virtual. You declare them in the abstract schema, but you do not code them as instance variables in the entity bean class. Instead, the persistent fields are identified in the code by access methods (getters and setters).

Relationship Fields

A relationship field is designed to represent and store a reference to another entity bean. This is analogous to a foreign key in a relational database table. Unlike a persistent field, a relationship field does not constitute the state of an entity bean.

An OrderEJB entity bean, for example, might have relationship fields such as lineItems and student.

Abstract Persistent Schema

The CMP entity bean's deployment descriptor contains a description of the bean's abstract persistent schema. This schema is an abstract representation of an entity bean's persistent fields and relationship fields. The abstract schema is independent of the entity bean's implementation in a particular EJB container or particular database.

For example, the following snippet declares an abstract persistent schema named Order in the deployment descriptor:

. . .
<cmp-version>2.x</cmp-version>
<abstract-schema-name>Order</abstract-schema-name>
<cmp-field>
   <field-name>orderId</field-name>
</cmp-field>
 <cmp-field>
   <field-name>orderDate</field-name>
 </cmp-field>
 <cmp-field>
   <field-name>status</field-name>
 </cmp-field>
 <cmp-field>
   <field-name>amount</field-name>
 </cmp-field>
 . . .

The cmp-version must be 2.x if you want to take advantage of EJB 2.0 container-managed persistence. The schema declares four container-managed persistent fields (cmp-field): orderId, orderDate, status, and amount. The names of these fields must match the abstract get and set methods in your entity bean class. For example, your entity bean class's methods must be getOrderId, setOrderId, getOrderDate, setOrderDate, getStatus, setStatus, getAmount, and setAmount.

The EJB Query Language

The EJB Query language (EJB QL) is new in EJB 2.0. EJB QL is similar to SQL. It enables you to specify queries of entity bean methods in a database-independent, portable way. For example, the following code line illustrates how the application uses an EJB QL query of the method findOrdersByStatus(String status) to find orders of a particular status, such as COMPLETE:

SELECT OBJECT(o) FROM Order AS o WHERE o.status = ?1

The preceding query returns Order objects, as indicated by the expression OBJECT(o). The identifier o is analogous to an SQL correlation variable. The WHERE clause limits the orders to those whose status matches the value of the first parameter passed to the query, which is denoted by the expression ?1.

The container tools will translate such queries into the target language of the underlying database. For example, in case of a relational database, the container translates an EJB QL query into an SQL query.

Note

Entity beans with container-managed persistence are portable. Their code is not tied to a specific database.


You will learn more about container-managed persistence on Day 11, “Developing Container-Managed Persistence Entity Beans,” and on Day 12, “Developing Container-Managed Relationship Entity Beans.”

When to Use BMP or CMP

The choice between BMP and CMP is often decided by factors such as portability, availability of container tools, flexibility, and so on.

Using BMP

Typically, you would use bean-managed persistence in the following situations:

  • When you want complete control of managing persistence, such as writing optimized queries.

  • When you're writing persistence logic to a very proprietary legacy database system for which container tools do not exist.

  • When your persistent store is not a database, you might wrap an existing application using an entity bean.

Using CMP

With container-managed persistence, the container takes responsibility for generating the data access code. This simplifies the task of writing entity beans.

The CMP entity bean's code is not tied to a specific persistent storage mechanism (database). Because of this flexibility, even if you redeploy the same entity bean on different J2EE servers that use different databases, you won't need to modify or recompile the bean's code. In short, your CMP entity beans are more portable than BMP entity beans.

Tip

Whenever possible, you should use container-managed persistence beans because they are portable and easier to develop than bean-managed persistence beans.


Instance Pool and Instance Cache

Just as with stateless session beans, an EJB container may maintain an instance pool of each type of entity bean. This saves the precious time of creating and destroying of objects. At startup, the container creates instances as specified in the deployment descriptor of the entity bean. While the instance is in the available pool, the instance is not associated with any particular entity object identity. All instances in the pool are considered equivalent; therefore, an instance can be assigned by the container to any entity object identity. You can control the instance pool size in the vendor-specific deployment descriptor.

For example, you can specify the pool size in the deployment descriptor weblogic-ejb-jar.xml for WebLogic Server as follows:

<pool>
  <max-beans-in-free-pool>100</max-beans-in-free-pool>
  <initial-beans-in-free-pool>50</initial-beans-in-free-pool>
</pool>

Similarly, you can specify the pool size in the deployment descriptor jboss.xml for the JBoss server as follows:

<instance-pool>org.jboss.ejb.plugins.EntityInstancePool</instance-pool>
<container-pool-conf>
  <MaximumSize>100</MaximumSize>
  <MinimumSize>10</MinimumSize>
</container-pool-conf>

Just as with stateful session beans, the EJB container can have an instance cache to manage all entity bean instances that are associated with an identity. In large applications, the number of clients connected concurrently to a Web site can be in the thousands. This can have an adverse effect on performance when resources are used up. Passivation and activation are mechanisms provided by the EJB container to manage valuable resources, such as memory, in order to reduce the number of entity bean instances needed to service all concurrent clients.

Passivation is the mechanism by which the EJB container stores the bean's state into the database. The container starts passivation as soon as the number of allocated entity beans exceeds a certain threshold. The EJB container provides the bean developer with ejbPassivate() as a callback method to release any allocated resources. Activation, on the other hand, is the process of restoring back the bean from the database. The EJB container activates a passivated instance when the bean's client references the bean instance. The EJB container provides the bean developer with ejbActivate() as a callback method to restore any connections and other resources.

For example, you can specify the instance cache size in deployment descriptor weblogic-ejb-jar.xml for WebLogic Server as follows:

<entity-cache>
 <max-beans-in-cache>1000</max-beans-in-cache>
</entity-cache>

Similarly, you can specify the instance cache size in deployment descriptor jboss.xml for JBoss server as follows:

<instance-cache>
<container-cache-conf>
 <cache-policy>
  <cache-policy-conf>
    <min-capacity>5</min-capacity>
    <max-capacity>10</max-capacity>
  </cache-policy-conf>
 </cache-policy>
</container-cache-conf>
</instance-cache>

Note

Instance pooling is used to manage EJB instances that are not associated with any identity. Instance caching is used to manage EJB instances that are associated with an identity. Instance pooling is applicable to stateless session, entity, and message-driven beans, whereas instance caching is applicable to stateful session and entity beans.


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

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