Skip Headers

Oracle Application Server Containers for J2EE Enterprise JavaBeans Developer's Guide 10g (9.0.4) Part Number B10324-01 |
Home | Contents | Index

# 3
CMP Entity Beans

This chapter demonstrates simple Container Managed Persistence (CMP) EJB development with a basic configuration and deployment. Download the CMP entity bean example (`cmpapp.jar`) from the OC4J sample code page on the OTN Web site.

This chapter demonstrates the following:

- Entity Bean Overview

- Transaction Requirements

- Creating Entity Beans

- Primary Key

- Persistence Fields

- Converstion of CMP Types to Database Types

See Chapter 6, "BMP Entity Beans", for an example of how to create a simple bean-managed persistent entity bean. For a description of persisting object relationships between EJBs, see Chapter 4, "Entity Relationship Mapping".

## Entity Bean Overview

With EJB 2.0 and the local interface support, most developers agree that entity beans should be paired with a session bean, servlet, or JSP that acts as the client interface. The entity bean is a coarse-grain bean that encapsulates functionality and represents data and dependent objects. Thus, you decouple the client from the data so that if the data changes, the client is not affected. For efficiency, the session bean, servlet, or JSP can be collocated with entity beans and can coordinate between multiple entity beans through their local interfaces. This is known as a session facade design. See the `http://java.sun.com` Web site for more information on session facade design.

An entity bean can aggregate objects together and effectively persist data and related objects under the umbrella of transactional, security, and concurrency support through the container. This and the following chapters focus on how to use the persistence functionality of the entity bean.

An entity bean manages persistent data in one of two ways: container-managed persistence (CMP) and bean-managed persistence (BMP). The primary difference between the two is as follows:

- Container-managed persistence--The EJB container manages data by saving it to a designated resource, which is normally a database. For this to occur, you must define the data that the container is to manage within the deployment descriptors. The container manages the data by saving it to the database.

- Bean-managed persistence--The bean implementation manages the data within callback methods. All the logic for storing data to your persistent storage must be included in the `ejbStore` method and reloaded from your storage in the `ejbLoad` method. The container invokes these methods when necessary.

  Note: This book does not cover EJB container services. See the JTA, Data Source, and JNDI chapters in the Oracle Application Server Containers for J2EE Services Guide for more information. For security, see the Oracle Application Server Containers for J2EE Security Guide.

## Transaction Requirements

All entity beans with CMP and CMR relationships must be involved in a transaction. As such, you cannot define any entity bean with a transaction attribute of NEVER, SUPPORTS, or NOT_REQUIRED as this would put the entity outside of a transaction.

## Creating Entity Beans

The following steps are an overview of what you must do in creating an entity bean, all of which are described fully in Chapter 2, "EJB Primer".

1. Create the home interfaces for the bean. The home interface defines the `create` and finder methods, including `findByPrimaryKey`, for your bean. See "Home Interface".

2. Create the component interfaces for the bean. The component interfaces declare the methods that a client can invoke. See "Component Interfaces".

3. Define the primary key for the bean. The primary key identifies each entity bean instance and is a serializable class. You can use a simple data type class, such as `java.lang.String`, or define a complex class, such as one with two or more objects as components of the primary key. See "Primary Key".

4. Implement the bean. See "Entity Bean Class".

5. Create the bean deployment descriptor. The deployment descriptor specifies properties for the bean through XML elements. This step is where you identify the data within the bean that is to be managed by the container. See "Persistence Fields" for more information on persistence fields. If these fields describe relationships to other objects, see Chapter 4, "Entity Relationship Mapping".

   Any EJB Container services that you want to configure is also designated in the deployment descriptor. For information about data sources and JTA, see the Oracle Application Server Containers for J2EE Services Guide. For information about security, see the Oracle Application Server 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 datasource 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 the EJB to OC4J.

The following sections demonstrate a simple CMP entity bean. This example continues the use of the employee example, as in other chapters--without adding complexity.

- Home Interface

- Component Interfaces

- Entity Bean Class

### Home Interface

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

- The local home interface extends `javax.ejb.EJBLocalHome`.

- The remote home interface extends `javax.ejb.EJBHome`.

The home interface must contain a `create` method, which the client invokes to create the bean instance. Each `create` method can have a different signature. For an entity bean, you must develop a `findByPrimaryKey` method. Optionally, you can develop other finder methods, which are named `find<``name``>`, for the bean.

In addition to creation and retrieval methods, you can provide home interface business methods within the home interface. The functionality within these methods cannot access data of a particular entity object. Instead, 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.

Our employee example provides the local home interface with a `create`, `findByPrimaryKey`, `findAll`, and `calcSalary` methods. The `calcSalary` 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.

#### Example 3-1 Entity Bean Employee Home Interface

The employee home interface provides a method to create the component interface. It also provides two finder methods: one to find a specific employee by an employee number and one that finds all employees. Last, it supplies a home interface business method, `calcSalary`, to calculate how much all employees cost the business.

The home interface is required to extend `javax.ejb.EJBHome` and define the `create` and `findByPrimaryKey` methods.

    package employee;

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

    public interface EmployeeLocalHome extends EJBLocalHome
    {

      public EmployeeLocal create(Integer empNo) throws CreateException;

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

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

      //Calculate the Salaries of all employees
      public float calcSalary() throws Exception;
    }

### Component Interfaces

The entity bean component interfaces are the interfaces that the customer sees and invokes methods upon. The component interface defines the business logic methods for the entity bean instance.

- The local component interface extends `javax.ejb.EJBLocalObject`.

- The remote component interface extends `javax.ejb.EJBObject`.

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 getEmpNo();
      public void setEmpNo(Integer empNo);

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

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

### Entity Bean Class

The entity bean class implements the following methods:

- The target methods for the methods that are declared in the 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--although you must still provide an empty method for each of these.

  - any home interface business methods, which are prepended with `ejbHome` in the bean implementation. For example, the `calcSalary` method is implemented in the `ejbHomeCalcSalary` method.

- The business logic methods that are declared in the component interfaces.

- The methods that are inherited from the `javax.ejb.EntityBean` interface.

However, with container-managed persistence, the container manages most of the target methods and the data objects, thereby leaving little for you to implement.

    package employee;

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

    public abstract class EmployeeBean implements EntityBean
    {

      private EntityContext ctx;

      // Each CMP field has a get and set method as accessors
      public abstract Integer getEmpNo();
      public abstract void setEmpNo(Integer empNo);

      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 ejbHomeCalcSalary() 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();
           }
           return totalSalary;
        }
        catch (FinderException e) {
          System.out.println("Got finder Exception "+e.getMessage());
          throw new Exception(e.getMessage());
        }
      }

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

      public void ejbPostCreate(Integer empNo, 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;
      }
    }

Note: The entire CMP entity bean example (`cmpapp.jar`) is available on OTN from the OC4J sample code page on the OTN Web site.

## Primary Key

Each entity bean instance has a primary key that uniquely identifies it from other instances. You must declare the primary key (or the fields contained within a complex primary key) as a container-managed persistent field in the deployment descriptor. All fields within the primary key are restricted to either primitive, serializable, or types that can be mapped to SQL types. You can define your primary key in one of two ways:

- Define the type of the primary key to be a well-known type. The type is defined in the `<prim-key-class>` in the deployment descriptor. The data field that is identified as the persistent primary key is identified in the `<primkey-field>` element in the deployment descriptor. The primary key variable that is declared within the bean class must be declared as `public`.

- Define the type of the primary key as a serializable object within a <`name`>`PK` class that is serializable. This class is declared in the `<prim-key-class>` element in the deployment descriptor. This is an advanced method for defining a primary key and is discussed in "Defining the Primary Key in a Class".

- Specify an auto-generated primary key: If you specify a `java.lang.Object` as the primary key class type in `<prim-key-class>`, but do not specify the primary key name in `<primkey-field>`, then the primary key is auto-generated by the container. See Defining an Auto-Generated Primary Key for more information.

For a simple CMP, you can define your primary key to be a well-known type by defining the data type of the primary key within the deployment descriptor.

The employee example defines its primary key as a `java.lang.Integer` and uses the employee number (`empNo`) as its primary key.

    <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>empNo</field-name></cmp-field>
             <cmp-field><field-name>empName</field-name></cmp-field>
             <cmp-field><field-name>salary</field-name></cmp-field>
            <primkey-field>empNo</primkey-field>
          </entity>
    ...
    </enterprise-beans>

Once defined, the container creates a column in the entity bean table for the primary key and maps the primary key defined in the deployment descriptor to this column.

Note: The entire CMP entity bean example (`cmpapp.jar`) is available on OTN from the OC4J sample code page on the OTN Web site.

Within the `orion-ejb-jar.xml` file, the primary key is mapped to the underlying database persistence storage by mapping the CMP field or primary key field defined in the `ejb-jar.xml` file to the database column name. In the following `orion-ejb-jar.xml` fragment, the `EmpBean` persistence storage is defined as the `EMP` table in the database that is defined in the `jdbc/OracleDS` data source. Following the `<entity-deployment>` element definition, the primary key, `empNo`, is mapped to the `EMPNO` column in the `Emp` table, and the `empName` and `salary` CMP fields are mapped to `EMPNAME` and `SALARY` columns respectively in the `EMP` table.

    <entity-deployment name="EmpBean" ...table="EMP"

                     data-source="jdbc/OracleDS"...   >
     <primkey-mapping>
      <cmp-field-mapping name="empNo" persistence-name="EMPNO" />
     </primkey-mapping>
     <cmp-field-mapping name="empName" persistence-name="EMPNAME" />
     <cmp-field-mapping name="salary" persistence-name="SALARY" />

### Defining the Primary Key in a Class

If your primary key is more complex than a simple data type, your primary key must be a class that is serializable of the name `<``name``>PK`. You define the primary key class within the `<prim-key-class>` element in the deployment descriptor.

The primary key variables must adhere to the following:

- Be defined within a `<cmp-field><field-name>` element in the deployment descriptor. This enables the container to manage the primary key fields.

- Be declared within the bean class as `public` and restricted to be either primitive, serializable, or types that can be mapped to SQL types.

- The names of the variables that make up the primary key must be the same in both the `<cmp-field><field-name>` elements and in the primary key class.

Within the primary key class, you implement a constructor for creating a primary key instance. Once the primary key class is defined in this manner, the container manages the class.

The following example places the employee number within a primary key class.

    package employee;

    public class EmployeePK implements java.io.Serializable
    {
      public Integer empNo;

      public EmployeePK()
      {
        this.empNo = null;
      }

      public EmployeePK(Integer empNo)
      {
        this.empNo = empNo;
      }
    }

The primary key class is declared within the `<prim-key-class>` element, and each of its variables are declared within a `<cmp-field><field-name>` element in the XML deployment descriptor, as follows:

    <enterprise-beans>
          <entity>
             <description>no description</description>
             <display-name>EmployeeBean</display-name>
             <ejb-name>EmployeeBean</ejb-name>
             <local-home>employee.LocalEmployeeHome</home>
             <local>employee.LocalEmployee</remote>
             <ejb-class>employee.EmployeeBean</ejb-class>
             <persistence-type>Container</persistence-type>
            <prim-key-class>employee.EmployeePK</prim-key-class>
             <reentrant>False</reentrant>
             <cmp-version>2.x</cmp-version>
             <abstract-schema-name>Employee</abstract-schema-name>
            <cmp-field><field-name>empNo</field-name></cmp-field>
             <cmp-field><field-name>empName</field-name></cmp-field>
             <cmp-field><field-name>salary</field-name></cmp-field>
          </entity>
    </enterprise-beans>

Once defined, the container creates a column in the entity bean table for the primary key and maps the primary key class defined in the deployment descriptor to this column.

The CMP fields are mapped in the `orion-ejb-jar.xml` in the same manner as described in "Primary Key". With a complex primary key, the mapping contains more than a single field; thus, the `<cmp-field-mapping>` element of the `<primkey-mapping>` element contains another subelement: the `<fields>` element. All of the fields of a primary key are each defined in a separate `<cmp-field-mapping>` element within the `<fields>` element, as shown below.

    <primkey-mapping>
     <cmp-field-mapping>
       <fields>
        <cmp-field-mapping name="empNo" persistence-name="EMPNO" />
       </fields>
     </cmp-field-mapping>
    </primkey-mapping>

Special mapping needs to happen if you have a complex primary key that contains a foreign key. See "Using a Foreign Key in a Composite Primary Key" for directions.

### Defining an Auto-Generated Primary Key

If you specify a `java.lang.Object` as the primary key class type in `<prim-key-class>`, but do not specify the primary key name in `<primkey-field>`, then the primary key is auto-generated by the container.

The employee example defines its primary key as a `java.lang.Object`. Thus, the container auto-generates the primary key.

    <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.Object</prim-key-class>
             <reentrant>False</reentrant>
             <cmp-version>2.x</cmp-version>
             <abstract-schema-name>Employee</abstract-schema-name>
             <cmp-field><field-name>empNo</field-name></cmp-field>
             <cmp-field><field-name>empName</field-name></cmp-field>
             <cmp-field><field-name>salary</field-name></cmp-field>
          </entity>
    ...
    </enterprise-beans>

Once defined, the container creates a column called `autoid` in the entity bean table for the primary key of type `LONG`. The container uses random numbers for the primary key values. This is generated in the `orion-ejb-jar.xml` for the bean, as follows:

    <primkey-mapping>
      <cmp-field-mapping name="auto_id"
                                          persistence-name="autoid"/>
    </primkey-mapping>

## Persistence Fields

The persistent data in your CMP bean can be one of the following:

- Persistence field--Simple data type that is persisted to a database table. This field is a direct attribute of the bean.

- Relationship field--Relationship to another bean.

Each type results in its own complex rules of how to configure. This section discusses persistence fields. For information on relationship fields, see Chapter 4, "Entity Relationship Mapping".

In CMP entity beans, you define the persistent data both in the bean instance and in the deployment descriptor.

- Get/Set methods in the bean instance: For each persistence and relationship field, both a get and a set method is created. For persistence fields, the data type of the parameter returned from the get method and passed into the set method defines the simple data type of the field. The name of the field is designated by the name of the get and set methods.

  The following XML shows the get and set methods for the employee name persistence field. A `String` is passed back from the get method and into the set method. Thus, the `String` is the simple data type of the field. If you remove the "get" and "set" from the method names and then lower the case of the first letter, you have the persistence field name. In this case, `empName` is the persistence field name.

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

- The deployment descriptor defines these fields as persistent. Each field name must be defined in a `<cmp-field><field-name>` element in the EJB deployment descriptor. In the employee example, three persistence data fields are defined in the data accessor methods: `empNo`, `empName`, and `salary`.

  These fields are defined as persistent fields in the `ejb-jar.xml` deployment descriptor within the `<cmp-field><field-name>` element, as follows:

      <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>empNo</field-name></cmp-field>
               <cmp-field><field-name>empName</field-name></cmp-field>
               <cmp-field><field-name>salary</field-name></cmp-field>
               <primkey-field>empNo</primkey-field>
            </entity>
      ...
      </enterprise-beans>

For these fields to be mapped to a database, you can do one of the following:

- Accept the defaults for these fields and avoid more deployment descriptor configuration. See "Default Mapping of Persistent Fields to the Database" on how the default mapping occurs.

- Map the persistent data fields to columns in a table that exists in a designated database. The persistent data mapping is configured within the `orion-ejb-jar.xml` file. See "Explicit Mapping of Persistent Fields to the Database" for more information.

  Note: The entire CMP entity bean example (`cmpapp.jar`) is available on OTN from the OC4J sample code page on the OTN Web site.

### Default Mapping of Persistent Fields to the Database

If you simply define the persistent fields in the `ejb-jar.xml` file, then OC4J provides the following mappings of these fields to the database:

- Database--The default database as set up in your OC4J instance configuration. For the JNDI name, use the `<location>` element for emulated data sources and `<ejb-location>` element for non-emulated data sources.

  Upon installation, the default database is a locally installed Oracle database that must be listening on port 1521 with a SID of `ORCL`. To customize the default database, change the first configured database to point to your database.

  Note: See the Data Source chapter in the Oracle Application Server Containers for J2EE Services Guide for more information on configuring Data Source objects.

- Table--The container automatically creates a default table where the name of the table is guaranteed to be unique. For all future redeployments, copy the generated `orion-ejb-jar.xml` file with this table name into the same directory as your `ejb-jar.xml` file. Thus, all future redeployments have the same table names as first generated. If you do not copy this file over, different table names may be generated.

  The table name is constructed with the following names, where each is separated by an underscore (_):

  - EJB name defined in `<ejb-name>` in the deployment descriptor.

  - JAR file name, including the .`jar` extension. However, all dashes (-) and periods (.) are converted to underscores (_) to follow SQL conventions. For example, if the name of your JAR file is `employee.jar`, then `employee_jar` is appended to the name.

  - Application name: This is the name of the application name, which you define during deployment.

  If the constructed name is greater than thirty characters, the name is truncated at twenty-four characters. Then six characters made up of an alphanumeric hash code is appended to the name.

  For example, if the EJB name is `EmpBean`, the JAR file is `empl.jar`, and the application name is `employee`, then the default table name is `EmpBean_empl_jar_employee`.

- Column names--The columns in the entity bean table each have the same name as the `<cmp-field>` elements in the designated database. The data types for the database, translating Java data types to database data types, are defined in the specific database XML file, such as `oracle.xml`.

  Note: Auto-creation of tables in third-party databases may fail for certain data types unless the persistent-type mapping for VARCHAR is defined in the `orion-ejb-jar.xml` as follows: `<cmp-field-mapping name="../" persistence-name="..." persistence-type="varchar(10)" />`

### Explicit Mapping of Persistent Fields to the Database

As "Default Mapping of Persistent Fields to the Database" discusses, your persistent data can be automatically mapped to a database table by the container. However, if the data represented by your bean is more complex or you do not want to accept the defaults that OC4J provides for you, then you can map the persistent data to an existing database table and its columns within the `orion-ejb-jar.xml` file. Once the fields are mapped, the container provides the persistence storage of the persistent data to the indicated table and rows.

For explicit mapping, Oracle recommends that you do the following:

1. Deploy your application with only the `ejb-jar.xml` elements configured.

   OC4J creates an `orion-ejb-jar.xml` file for you with the default mappings in them. It is easier to modify these fields than to create them from scratch. This provides you a method for choosing all or part of the modifications that are discussed in this section.

2. Modify the `<entity-deployment>` element in the `orion-ejb-jar.xml` file to use the database table and columns you specify.

Once you define persistent fields, each within its own `<cmp-field>` element, you can map each to a specific database table and column. Thus, you can map CMP fields to existing database tables. The mapping occurs with the OC4J-specific deployment descriptor: `orion-ejb-jar.xml`.

The explicit mapping of CMP fields is completed within an `<entity-deployment>` element. This element contains all mapping for an entity bean. However, the attributes and elements that are specific to CMP field mapping is as follows:

    <entity-deployment name="..." location="..."

    	table="..." data-source="...">
    	<primkey-mapping>
    		<cmp-field-mapping name="..." persistence-name="..." />
    	</primkey-mapping>
    	<cmp-field-mapping name="..." persistence-name="..." />
    ...
    </entity-deployment>

Element or Attribute Name | Description
--- | ---
`name` | Bean name, which is defined in the `ejb-jar.xml` file in the `<ejb-name>` element.
`location` | JNDI location
`table` | Database table name
`data-source` | Data source for the database where the table resides
`primkey-mapping` | Definition of how the primary key is mapped to the table.
`cmp-field-mapping` | The `name` attribute specifies the `<cmp-field>` in the deployment descriptor, which is mapped to a table column in the `persistence-name` attribute.

You can configure the following within the `orion-ejb-jar.xml` file:

1. Configure the `<entity-deployment>` element for every entity bean that contains CMP fields that will be mapped within it.

2. Configure a `<cmp-field-mapping>` element for every field within the bean that is mapped. Each `<cmp-field-mapping>` element must contain the name of the field to be persisted.

   1. Configure the primary key in the `<primkey-mapping>` element contained within its own `<cmp-field-mapping>` element.

   2. Configure simple data types (such as a primitive, simple object, or serializable object) that are mapped to a single field within a single `<cmp-field-mapping>` element. The name and database field are fully defined within the element attributes.

#### Example 3-2 Mapping Persistent Fields to a Specific Database Table

The following example demonstrates how to map persistent data fields in your bean instance to database tables and columns by mapping the employee persistence data fields to the Oracle database table `EMP`.

- The bean is identified in the `<entity-deployment>` `name` attribute. The JNDI name for this bean is defined in the `location` attribute.

- The database table name is defined in the `table` attribute. And the database is specified in the `data-source` attribute, which should be identical to the `<ejb-location>` name of a `DataSource` defined in the `data-sources.xml` file.

- The bean primary key, `empNo`, is mapped to the database table column, `EMPNO`, within the `<primkey-mapping>` element.

- The bean persistent data fields, `empName` and `salary`, are mapped to the database table columns `ENAME` and `SAL` within the `<cmp-field-mapping>` element.

      <entity-deployment name="EmpBean" location="emp/EmpBean"

      	wrapper="EmpHome_EntityHomeWrapper2" max-tx-retries="3"

      	table="emp" data-source="jdbc/OracleDS">
      	<primkey-mapping>
      		<cmp-field-mapping name="empNo" persistence-name="empno" />
      	</primkey-mapping>
      	<cmp-field-mapping name="empName" persistence-name="ename" />
      	<cmp-field-mapping name="salary" persistence-name="sal" />
        ...
      </entity-deployment>

After deployment, OC4J maps the element values to the following:

Bean | Database
--- | ---
`emp/EmpBean` | EMP table, located at `jdbc/OracleDS` in the `data-sources.xml` file
`empNo` | `EMPNO` column as primary key
`empName` | `ENAME` column
`salary` | `SAL` column

## Converstion of CMP Types to Database Types

In defining the container-managed persistent fields in the `<cmp-field>` and the primary key types, you can define simple data types and Java user classes that are serializable.

- Simple Data Types

- Serializable Classes

- Other Entity Beans or Collections

### Simple Data Types

The following table provides a list of the supported simple data types, which you can provide in the `persistence-type` attribute, with the mapping of these types to SQL types and to Oracle database types. None of these mappings are guaranteed to work on non-Oracle databases.

Table 3-1 Simple Data Types

Known Type (native) | SQL type | Oracle type
--- | --- | ---
java.lang.String | VARCHAR(255) | VARCHAR2(255)
java.lang.Integer[ ] | INTEGER | NUMBER(20,0)
java.lang.Long[ ] | INTEGER | NUMBER(20,0)
java.lang.Short[ ] | INTEGER | NUMBER(10,0)
java.lang.Double[ ] | DOUBLE PRECISION | NUMBER(30,0)
java.lang.Float[ ] | FLOAT | NUMBER(20,5)
java.lang.Byte[ ] | SMALLINT | NUMBER(10,0)
java.lang.Character[ ] | CHAR | CHAR(1)
java.lang.Boolean[ ] | BIT | NUMBER(1,0)
java.util.Date | DATETIME | DATE
java.sql.Date | DATE | DATE
java.util.Time | DATE | DATE
java.sql.Timestamp | TIMESTAMP | TIMESTAMP
java.lang.String | CLOB | CLOB
char[ ] | CLOB | CLOB
byte[ ] | BLOB | BLOB
java.io.Serializable (4KB limit) | LONGVARBINARY | BLOB

Note: You can modify the mapping of these data types in the `config/database-schema/<db>.xml` XML configuration files.

The `Date` and `Time` map to `DATE` in the database, because the `DATE` contains the time. The `Timestamp`, however, maps to `TIMESTAMP` in the database, which gives the time in nanoseconds.

Mapping `java.sql.CLOB` and `java.sql.BLOB` directly is not currently supported because these objects are not serializable. However you can map a String or `char[]` and `byte[]` to database column type CLOB and BLOB respectively. Mapping a `char[]` to a CLOB or a `byte[]` to a BLOB can only be done with an Oracle database. The Oracle JDBC API was modified to handle this operation.

There is a 4 KB limit when mapping a serialized object to a BLOB type over the JDBC Thin driver.

When String and `char[]` variables map to a VARCHAR2 in the database, it can only hold up to 2K. However, you can map String object or `char[]` larger than 2K to a CLOB by doing the following:

1. The bean implementation uses the String or `char[]` objects.

2. The `persistence-type` attribute of the `<cmp-field-mapping>` element defines the object as a CLOB, as follows:

       	<cmp-field-mapping name="stringdata" persistence-name="stringdata"

                   persistence-type="CLOB" />

In the same manner, you can map a `byte[]` in the bean implementation to a BLOB, as follows:

    	<cmp-field-mapping name="bytedata" persistence-name="bytedata"

                persistence-type="BLOB" />

### Serializable Classes

In addition to simple data types, you can define user classes that implement `Serializable`. These classes are stored in a BLOB in the database.

### Other Entity Beans or Collections

You should not define other entity beans or `Collections` as a CMP type. Instead, these are relationships and should be defined within a CMR field.

- A relationship to another entity bean is always defined in a `<cmr-field>` relationship.

- `Collections` promote a "many" relationship and should be configured within a `<cmr-field>` relationship. Other types, such as `Lists`, are sub-interfaces of `Collections`. Oracle recommends that you use `Collections`.

| Copyright © 2002, 2003 Oracle Corporation. All Rights Reserved. |
Home | Contents | Index