Skip Headers
Oracle® Containers for J2EE Orion CMP Developer's Guide
10g Release 3 (10.1.3.1)

Part Number B28220-01
Go to Documentation Home
Home
Go to Book List
Book List
Go to Table of Contents
Contents
Go to Index
Index
Go to Feedback page
Contact Us

Go to previous page
Previous
Go to next page
Next
View PDF

4 Implementing an EJB 2.0 Entity Bean With Container-Managed Persistence

This chapter describes the ways to implement EJB 2.0 entity beans with container-managed persistence.

This chapter includes information on the following topics:

For more information, see:

Implementing an EJB 2.0 Entity Bean With Container-Managed Persistence

The process of implementing an EJB 2.0 entity bean with container-managed persistence consists of the following steps:

  1. Create the bean's home interface. The home interface defines the methods that allow a client to create, find, or remove an entity bean. See "Implementing the Entity Bean Home Interface" for more information.

  2. Create the component (remote) interfaces for the bean. The component interfaces declare the methods that a client can invoke. See "Implementing the Entity Bean Component Interface" for more information.

  3. Define the primary key for the bean. The primary key identifies each entity bean instance and is a serializable class. See "Configuring Primary Key" for more information.

  4. Implement the bean. See "Implementing the Entity Bean Class" for more information.

  5. Create the bean deployment descriptor–a file that specifies properties for the bean using XML elements. It is your responsibility to identify the data within the bean that the container will manage (see "Configuring Container-Managed Persistent Fields" for more information on persistence fields). If these fields describe relationships to other objects, see "Configuring Container-Managed Relationship Fields".

    Any EJB container services that you might want to configure are also designated in the deployment descriptor. For information about data sources and JTA, see Oracle Containers for J2EE Services Guide. For information about security, see Oracle Containers for J2EE Security Guide.

    If the persistent data is saved to or restored from a database, and you are not using the defaults provided by the container, then you must ensure that the correct tables exist for the bean. In the default scenario, the container creates the table and columns for your data based on deployment descriptor and data source information.

  6. Create an EJB JAR file containing the bean, component interface, home interface, and the deployment descriptors. Once created, configure the application.xml file, create an EAR file, and deploy your entity bean to OC4J. See Chapter 2, "Understanding Orion CMP Application Development" for more information.

For information on how to configure EJB 2.0 entity beans with container-managed persistence, see "Configuring an EJB 2.0 Entity Bean With Container-Managed Persistence".

Implementing the Entity Bean Home Interface

The home interface is primarily used for retrieving the bean reference, on which the client can request business methods. The following are the types of the home interface:

  • The remote home interface, which extends javax.ejb.EJBHome. This type of the home interface is provided by beans that provide a remote client view.

  • The local home interface, which extends javax.ejb.EJBLocalHome. This type of the home interface is provided by beans that provide a local client view.


Note:

If an entity bean is the target of a container-managed relationship, then it must have local interfaces.

A client can locate the bean's home interface through the standard JNDI API.

The home interface must contain a create method, which the client invokes to create the bean instance. The entity bean can have zero or more create methods, each with its own defined parameters.

Entity beans must define one or more finder methods, where at least one is a findByPrimaryKey method. Optionally, you can define other finder methods (named find<NAME>) for the bean.

In addition to creation and retrieval methods, you can provide business methods within the home interface. These methods cannot access data of a particular entity object. The purpose of these methods is to provide a way to retrieve information that is not related to a single entity bean instance. When the client invokes any home interface business method, an entity bean is removed from the pool to service the request. Thus, this method can be used to perform operations on general information related to the bean.

Example 4-1 Implementing the Entity Bean Home Interface

The home interface must extend javax.ejb.EJBHome interface, as well as define the create and findByPrimaryKey methods.

Example 4-1 demonstrates an implementation of a local home interface that provides a method to create the remote interface. It also provides two finder methods: one to find a specific employee by an employee number, and one that finds all employees. The calculateSalary method is a home interface business method that calculates the sum of all employee salaries. It does not access the information of a particular employee, but performs a SQL inquiry against the database for all employees.

package employee;

import javax.ejb.*;
import java.rmi.*;

public interface EmployeeLocalHome extends EJBLocalHome {

    public EmployeeLocal create(Integer empNumber) throws CreateException;

    // Find an existing employee
    public EmployeeLocal findByPrimaryKey (Integer empNumber) 
    throws FinderException;

    // Find all employees
    public Collection findAll() throws FinderException;

    // Calculate the salaries of all employees
    public float calculateSalary() throws Exception;
}

It is the responsibility of the EJB container to create an implementation for this interface.

Declaring the Home Interface in the Deployment Descriptor

The following is the declaration of the home interface in the deployment descriptor:

<local-home>employee.EmployeeLocalHome</local-home>

Implementing the Entity Bean Component Interface

An EJB object is accessible through the bean's component interface. The component interface (also often referred to as remote interface) defines the business methods that a client may call. The business methods are implemented in the entity bean code. The following are the types of the component interface:

  • The component interface that extends javax.ejb.EJBObject. The EJBObject interface defines the operations that let the client access the EJB object's identity and create a persistent handle for this object.

  • The component interface that extends javax.ejb.EJBLocalObject. The EJBLocalObject interface defines the operations that let the client to access this object's identity.

Example 4-2 Implementing the Entity Bean Component Interface

The employee entity bean example exposes the local component interface, which contains methods for retrieving and updating employee information.

package employee;

import javax.ejb.*;

public interface EmployeeLocal extends EJBLocalObject {

    public Integer getEmpNumber();
    public void setEmpNumber(Integer empNumber);

    public String getEmpName();
    public void setEmpName(String empName);

    public Float getSalary();
    public void setSalary(Float salary);

}

It is the responsibility of the EJB container to create an implementation for the component interface.

Declaring the Component Interface in the Deployment Descriptor

The following is the declaration of the component interface in the deployment descriptor:

<local>employee.EmployeeLocal</local>

Implementing the Entity Bean Class

An entity bean class must meet the following criteria:

  • The class must implement, directly or indirectly, the javax.ejb.EntityBean interface.

  • The class must be defined as public and must be abstract.

  • The class must define a public constructor that takes no arguments.

  • The class must not define the finalize() method.

The class may, but is not required to, implement the entity bean's component interface (see "Implementing the Entity Bean Component Interface").

The entity bean class implements the following methods:

  • The target methods for the methods that are declared in the home interface (see "Implementing the Entity Bean Home Interface"), which include the following:

    • The ejbCreate and ejbPostCreate methods with parameters matching the associated create method defined in the home interface.

    • Finder methods, other than ejbFindByPrimaryKey and ejbFindAll, that are defined in the home interface. The container generates the ejbFindByPrimaryKey and ejbFindAll method implementations.

    • Any home interface business methods, which have an ejbHome prefix in the bean implementation. For example, the calculateSalary method is implemented in the ejbHomeCalculateSalary method.

  • The business logic methods that are declared in the component interface.

  • The methods that are inherited from the javax.ejb.EntityBean interface (such as ejbActivate, ejbPassivate, and so forth).

It is the responsibility of the container to manage most of the target methods and the data objects. For information about the entity bean's callback methods, see "Callback Methods".

Example 4-3 Implementing the Entity Bean Class

Example 4-3 demonstrates the implementation of the entity bean class.

package employee;

import javax.ejb.*;
import java.rmi.*;

public abstract class EmployeeBean implements EntityBean {

  private EntityContext ctx;

  // Each persistent field has a getter and a setter 
  public abstract Integer getEmpNumber();
  public abstract void setEmpNumber(Integer empNumber);

  public abstract String getEmpName();
  public abstract void setEmpName(String empName);

  public abstract Float getSalary();
  public abstract void setSalary(Float salary);

  public void EmployeeBean() {
    // Constructor. Do not initialize anything in this method. 
    // All initialization should be performed in the ejbCreate method.
    // The passivate() method may destroy these attributes when pooling
  }

  public float ejbHomeCalculateSalary() throws Exception {
    Collection c = null;
    try {
      c = ((EmployeeLocalHome)this.ctx.getEJBLocalHome()).findAll();
      Iterator i = c.iterator();
      float totalSalary = 0;
      while (i.hasNext()) {
        EmployeeLocal e = (EmployeeLocal)i.next();
        totalSalary = totalSalary + e.getSalary().floatValue();
      }
    catch (FinderException e) {
      System.out.println("Got finder Exception " + e.getMessage());
      throw new Exception(e.getMessage());
    }
  }

  public EmployeePK ejbCreate(Integer empNumber, String empName, Float salary)
  throws CreateException {
    setEmpNumber(empNumber);
    setEmpName(empName);
    setSalary(salary);
    return new EmployeePK(empNumber);
  }

  public void ejbPostCreate(Integer empNumber, String empName, Float salary)
  throws CreateException {
    // Called just after bean created; container takes care of implementation 
  }

  public void ejbStore() {
    // Called when bean persisted; container takes care of implementation
  }

  public void ejbLoad() {
    // Called when bean loaded; container takes care of implementation
  }

  public void ejbRemove() throws RemoveException {
    // Called when bean removed; container takes care of implementation 
  }

  public void ejbActivate() {
    // Called when bean activated; container takes care of implementation.
    // If you need resources, retrieve them here
  }

  public void ejbPassivate() {
    // Called when bean deactivated; container takes care of implementation.
    // If you set resources in ejbActivate, remove them here
  }

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

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

}

Defining the Entity Bean Class in the Deployment Descriptor

You define the entity bean class in the deployment descriptor with the following line:

<ejb-class>employee.EmployeeBean</ejb-class> 

The following is the sample deployment descriptor for the entity bean:

<enterprise-beans>
    <entity> 
        <display-name>Employee</display-name>
        <ejb-name>EmployeeBean</ejb-name>
        <local-home>employee.EmployeeLocalHome</local-home>
        <local>employee.EmployeeLocal</local>
        <ejb-class>employee.EmployeeBean</ejb-class>
        <persistence-type>Container</persistence-type>
        <prim-key-class>java.lang.Integer</prim-key-class>
        <reentrant>False</reentrant>
        <cmp-version>2.x</cmp-version>
        <abstract-schema-name>Employee</abstract-schema-name>
        <cmp-field><field-name>empNumber</field-name></cmp-field>
        <cmp-field><field-name>empName</field-name></cmp-field>
        <cmp-field><field-name>salary</field-name></cmp-field>
        <primkey-field>empNumber</primkey-field>
    </entity>
...
</enterprise-beans>