# EJB Programmer's Guide: Developing Entity Beans

## Target Audience and Content

The target audience for this guide is the Enterprise Bean provider, i.e. the person in charge of developing the software components on the server side, and more specifically the Entity Beans.

The content of this guide is the following:

1. Target Audience and content
2. Introduction
3. The Home Interface
4. The Component Interface
5. The Primary Key Class
6. The Enterprise Bean Class
7. Writing Database Access Operations (bean-managed persistence)
8. Configuring Database Access for Container-managed Persistence
9. Tuning Container for Entity Bean Optimizations
10. Using CMP2.0 Persistence
    - Standard CMP2.0 Aspects
      - Entity Bean Implementation Class
      - Standard Deployment Descriptor
    - JOnAS EJBQL extension
    - LIMIT clause
    - JOnAS Database Mappers
    - JOnAS Database Mapping (Specific Deployment Descriptor)
      - Specifying and Initializing the Database
      - CMP fields Mapping
      - CMR fields Mapping to primary-key-fields (simple pk)
      - CMR fields Mapping to composite primary-keys

## Introduction

An Entity Bean is comprised of the following elements, which are developed by the Enterprise Bean Provider:

- The Component Interface is the client view of the bean. It contains all the "business methods" of the bean.
- The Home Interface contains all the methods for the bean life cycle (creation, suppression) and for instance retrieval (finding one or several bean objects) used by the client application. It can also contain methods called "home methods," supplied by the bean provider, for business logic which is not specific to a bean instance.
- The Primary Key class (for entity beans only) contains a subset of the bean's fields that identifies a particular instance of an entity bean. This class is optional since the bean programmer can alternatively choose a standard class (for example, java.lang.String)
- The bean implementation class implements the business methods and all the methods (described in the EJB specification) allowing the bean to be managed in the container.
- The deployment descriptor, containing the bean properties that can be edited at assembly or deployment time.

Note that, according to the EJB 2.0 specification, the couple "Component Interface and Home Interface" can be either local or remote. Local Interfaces (Home and Component) are to be used by a client running in the same JVM as the EJB component. Create and finder methods of a local (or remote) home interface return local (or remote) component interfaces. An EJB component may have both remote and local interfaces, even if normally only one type of interface is provided. If an entity bean is the target of a container-managed relationship (refer to EJB 2.0 persistence), then it must have local interfaces.

The description of these elements is provided in the following sections.

Note that in this documentation, the term "Bean" always means "Enterprise Bean."

An entity bean represents persistent data. It is an object view of an entity stored in a relational database. The persistence of an entity bean can be handled in two ways:

- Container-Managed Persistence: the persistence is implicitly managed by the container, no code for data access is supplied by the bean provider. The bean's state will be stored in a relational database according to a mapping description delivered within the deployment descriptor (CMP 1.1) or according to an implicit mapping (CMP 2.0).
- Bean-Managed Persistence: the bean provider writes the database access operations (JDBC code) in the methods of the enterprise bean that are specified for data creation, load, store, retrieval, and remove operations (ejbCreate, ejbLoad, ejbStore, ejbFind..., ejbRemove).

Currently, the platform handles persistence in relational storage systems through the JDBC interface. For both container-managed and bean-managed persistence, JDBC connections are obtained from an object provided at the EJB server level, the DataSource. The DataSource interface is defined in the JDBC 2.0 standard extensions. A DataSource object identifies a database and a means to access it via JDBC (a JDBC driver). An EJB server may propose access to several databases and thus provides the corresponding DataSource objects. DataSources are described in more detail in the section "Configuring JDBC DataSources."

## The Home Interface

In addition to "home business methods," the Home interface is used by any client application to create, remove, and retrieve instances of the entity bean. The bean provider only needs to provide the desired interface; the container will automatically provide the implementation. The interface must extend the `javax.ejb.EJBHome` interface if it is remote, or the `javax.ejb.EJBLocalHome` interface if it is local. The methods of a remote home interface must follow the rules for java RMI. The signatures of the "create" and "find..." methods should match the signatures of the "ejbCreate" and "ejbFind..." methods that will be provided later in the enterprise bean implementation class (same number and types of arguments, but different return types).

create methods:

- The return type is the enterprise bean's component interface.
- The exceptions defined in the throws clause must include the exceptions defined for the ejbCreate and ejbPostCreate methods, and must include `javax.ejb.CreateException` and `java.rmi.RemoteException` (the latter, only for a remote interface).

remove methods:

- The interfaces for these methods must not be defined, they are inherited from EJBHome or EJBLocalHome.
- The method is `void remove` taking as argument the primary key object or the handle (for a remote interface).
- The exceptions defined in the throws clause should be `javax.ejb.RemoveException` and `java.rmi.RemoteException` for a remote interface.
- The exceptions defined in the throws clause should be `javax.ejb.RemoveException` and `java.ejb.EJBException` for a local interface.

finder methods:

Finder methods are used to search for an EJB object or a collection of EJB objects. The arguments of the method are used by the entity bean implementation to locate the requested entity objects. For bean-managed persistence, the bean provider is responsible for developing the corresponding ejbFinder methods in the bean implementation. For container-managed persistence, the bean provider does not write these methods; they are generated at deployment time by the platform tools; the description of the method is provided in the deployment descriptor, as defined in the section "Configuring database access for container-managed persistence." In the Home interface, the finder methods must adhere to the following rules:

- They must be named "find<method>" (e.g. `findLargeAccounts`).
- The return type must be the enterprise bean's component interface, or a collection thereof.
- The exceptions defined in the throws clause must include the exceptions defined for the matching ejbFind method, and must include `javax.ejb.FinderException` and `java.rmi.RemoteException` (the latter, only for a remote interface).

At least one of these methods is mandatory: findByPrimaryKey, which takes as argument a primary key value and returns the corresponding EJB object.

home methods:

- Home methods are methods that the bean provider supplies for business logic that is not specific to an entity bean instance.
- The throws clause of every home method on the remote home interface includes the java.rmi.RemoteException.
- Home methods implementation is provided by the bean developer in the bean implementation class as public static methods named `ejbHome<METHOD_NAME>(...)`, where <METHOD_NAME> is the name of the method in the home interface.

### Example

The Account bean example, provided with the platform examples, is used to illustrate these concepts. The state of an entity bean instance is stored in a relational database, where the following table should exist, if CMP 1.1 is used:

`create table ACCOUNT (ACCNO integer primary key, CUSTOMER varchar(30), BALANCE number(15,4));`

`public interface AccountHome extends EJBHome {`

`public Account create(int accno, String customer, double balance)`
`throws RemoteException, CreateException;`

`public Account findByPrimaryKey(Integer pk)`
`throws RemoteException, FinderException;`

`public Account findByNumber(int accno)`
`throws RemoteException, FinderException;`

`public Enumeration findLargeAccounts(double val)`
`throws RemoteException, FinderException;`
`}`

## The Component Interface

Business methods:

The Component Interface is the client's view of an instance of the entity bean. It is what is returned to the client by the Home interface after creating or finding an entity bean instance. This interface contains the business methods of the enterprise bean. The interface must extend the `javax.ejb.EJBObject` interface if it is remote, or the `javax.ejb.EJBLocalObject` if it is local. The methods of a remote component interface must follow the rules for java RMI. For each method defined in this component interface, there must be a matching method of the bean implementation class (same arguments number and types, same return type, same exceptions except for RemoteException).

### Example

`public interface Account extends EJBObject {`
`public double getBalance() throws RemoteException;`
`public void setBalance(double d) throws RemoteException;`
`public String getCustomer() throws RemoteException;`
`public void setCustomer(String c) throws RemoteException;`
`public int getNumber() throws RemoteException;`
`}`

## The Primary Key Class

The Primary Key class is necessary for entity beans only. It encapsulates the fields representing the primary key of an entity bean in a single object. If the primary key in the database table is composed of a single column with a basic data type, the simplest way to define the primary key in the bean is to use a standard java class (for example, `java.lang.Integer` or `java.lang.String`). This must have the same type as a field in the bean class. It is not possible to define it as a primitive field (for example, int, float or boolean). Then, it is only necessary to specify the type of the primary key in the deployment descriptor:

          <prim-key-class>java.lang.Integer</prim-key-class>

And, for container-managed persistence, the field which represents the primary key:

          <primkey-field>accno</primkey-field>

The alternative way is to define its own Primary Key class, described as follows:

The class must be serializable and must provide suitable implementation of the `hashcode()` and `equals(Object)` methods.

For container-managed persistence, the following rules must be followed:

- The fields of the primary key class must be declared as public.
- The primary key class must have a public default constructor.
- The names of the fields in the primary key class must be a subset of the names of the container-managed fields of the enterprise bean.

### Example

`public class AccountBeanPK implements java.io.Serializable {`

> `public int accno;`

> `public AccountBeanPK(int accno) { this.accno = accno; }`

> `public AccountBeanPK() { }`

> `public int hashcode() { return accno; }`

> `public boolean equals(Object other) {`

> > `...`

> `}`

`}`

### Special case: Automatic generation of primary keys field

There are two ways to manage the automatic primary key with JOnAS. The first method is closer to what is described in the EJB specification, i.e. an automatic PK is a hidden field, the type of which is not known even by the application. The second method is to declare a usual PK CMP field of type java.lang.Integer as automatic. The two cases are described below.

#### 1) Standard automatic primary keys (from JOnAS 4.0.0)

In this case, an automatic PK is a hidden field, the type of which is not known even by the application. All that is necessary is to stipulate in the standard deployment descriptor that this EJB has an automatic PK, by specifying java.lang.Object as primkey-class. The primary key will be completely hidden to the application (no CMP field, no getter/setter method). This is valid for both CMP 2.x and CMP1 entity beans. The container will create an internal CMP field and generate its value when the entity bean is created.

Example:

Standard deployment descriptor:

      <entity>
        ...
        <ejb-name>AddressEJB</ejb-name>
        <local-home>com.titan.address.AddressHomeLocal</local-home>
        <local>com.titan.address.AddressLocal</local>
        <ejb-class>com.titan.address.AddressBean</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>Cmp2_Address</abstract-schema-name>
        <cmp-field><field-name>street</field-name></cmp-field>
        <cmp-field><field-name>city</field-name></cmp-field>
        <cmp-field><field-name>state</field-name></cmp-field>
        <cmp-field><field-name>zip</field-name></cmp-field>

Address Bean Class extract:

       // Primary key is not explicitly initialized during ejbCreate method
       // No cmp field corresponds to the primary key
       public Integer ejbCreateAddress(String street, String city,
            String state, String zip ) throws javax.ejb.CreateException {
         setStreet(street);
         setCity(city);
         setState(state);
         setZip(zip);
         return null;
       }

If nothing else is specified, and the JOnAS default CMP 2 database mapping is used, the JOnAS container will generate a database column with name JPK_ to handle this PK. However, it is possible to specify in the JOnAS-specific Deployment Descriptor the name of the column that will be used to store the PK value in the table, using the specific <automatic-pk-field-name> element, as follows (this is necessary for CMP2 legacy and for CMP1):

JOnAS-specific deployment descriptor:

      <jonas-ejb-jar xmlns="http://www.objectweb.org/jonas/ns"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.objectweb.org/jonas/ns http://www.objectweb.org/jonas/ns/jonas-ejb-jar_4_0.xsd" >
      <jonas-entity>
         <ejb-name>AddressEJB</ejb-name>
         <jdbc-mapping>
            <jndi-name>jdbc_1</jndi-name>
            <automatic-pk-field-name>FieldPkAuto</automatic-pk-field-name>
         </jdbc-mapping>
      </jonas-entity>

#### 2) CMP field as automatic primary key (was already in JOnAS 3.3.x)

The idea is to declare a usual PK CMP field of type java.lang.Integer as automatic, then it no longer appears in create methods and its value is automatically generated by the container at EJB instance creation time. But it is still a cmp field, with getter/setter methods, accessible from the application. Example:

In the standard DD, there is a usual primary key definition,

      <entity>
         ...
         <prim-key-class>java.lang.Integer</prim-key-class>
         <cmp-field><field-name>id</field-name></cmp-field>
         <primkey-field>id</primkey-field>

and in the JOnAS-specific Deployment Descriptor, it should be specified that this PK is automatic,

      <jonas-entity>
         ...
         <jdbc-mapping>

         <automatic-pk>true</automatic-pk>

Note: The automatic primary key is given a unique ID by an algorithm that is based on the system time; therefore, IDs may be not sequential.

Important restriction: This algorithm will not work if used inside a cluster with the same entity bean that is being managed in several jonas servers.

## The Enterprise Bean Class

The EJB implementation class implements the bean's business methods of the component interface and the methods dedicated to the EJB environment, the interface of which is explicitly defined in the EJB specification. The class must implement the `javax.ejb.EntityBean` interface, must be defined as public, cannot be abstract for CMP 1.1, and must be abstract for CMP 2.0 (in this case, the abstract methods are the get and set accessor methods of the bean cmp and cmr fields). Following is a list of the EJB environment dedicated methods that the EJB provider must develop.

The first set of methods are those corresponding to the create and find methods of the Home interface:

- public PrimaryKeyClass ejbCreate(...);

  This method is invoked by the container when a client invokes the corresponding create operation on the enterprise Bean's home interface. The method should initialize instance's variables from the input arguments. The returned object should be the primary key of the created instance. For bean-managed persistence, the bean provider should develop here the JDBC code to create the corresponding data in the database. For container-managed persistence, the container will perform the database insert after the ejbCreate method completes and the return value should be null.

- public void ejbPostCreate(...);

  There is a matching ejbPostCreate method (same input parameters) for each ejbCreate method. The container invokes this method after the execution of the matching ejbCreate(...) method. During the ejbPostCreate method, the object identity is available.

- public <PrimaryKeyClass or Collection> ejbFind<method> (...); // bean-managed persistence only

  The container invokes this method on a bean instance that is not associated with any particular object identity (some kind of class method ...) when the client invokes the corresponding method on the Home interface. The implementation uses the arguments to locate the requested object(s) in the database and returns a primary key (or a collection thereof). Currently, collections will be represented as `java.util.Enumeration objects` or `java.util.Collection`. The mandatory FindByPrimaryKey method takes as argument a primary key type value and returns a primary key object (it verifies that the corresponding entity exists in the database). For container-managed persistence, the bean provider does not have to write these finder methods; they are generated at deployment time by the EJB platform tools. The information needed by the EJB platform for automatically generating these finder methods should be provided by the bean programmer. The EJB 1.1 specification does not specify the format of this finder method description; for JOnAS, the CMP 1.1 finder methods description should be provided in the JOnAS-specific deployment descriptor of the Entity Bean (as an SQL query). Refer to the section "Configuring database access for container-managed persistence." The EJB 2.0 specification defines a standard way to describe these finder methods, i.e. in the standard deployment descriptor, as an EJB-QL query. Also refer to the section "Configuring database access for container-managed persistence." Then, the methods of the `javax.ejb.EntityBean` interface must be implemented:

  - public void setEntityContext(EntityContext ic);

    Used by the container to pass a reference to the EntityContext to the bean instance. The container invokes this method on an instance after the instance has been created. Generally, this method is used to store this reference in an instance variable.

  - public void unSetEntityContext();

    Unset the associated entity context. The container calls this method before removing the instance. This is the last method the container invokes on the instance.

  - public void ejbActivate();

    The container invokes this method when the instance is taken out of the pool of available instances to become associated with a specific EJB object. This method transitions the instance to the ready state.

  - public void ejbPassivate();

    The container invokes this method on an instance before the instance becomes dissociated with a specific EJB object. After this method completes, the container will place the instance into the pool of available instances.

  - public void ejbRemove();

    This method is invoked by the container when a client invokes a remove operation on the enterprise bean. For entity beans with bean-managed persistence, this method should contain the JDBC code to remove the corresponding data in the database. For container-managed persistence, this method is called before the container removes the entity representation in the database.

  - public void ejbLoad();

    The container invokes this method to instruct the instance to synchronize its state by loading it from the underlying database. For bean-managed persistence, the EJB provider should code at this location the JDBC statements for reading the data in the database. For container-managed persistence, loading the data from the database will be done automatically by the container just before ejbLoad is called, and the ejbLoad method should only contain some "after loading calculation statements."

  - public void ejbStore();

    The container invokes this method to instruct the instance to synchronize its state by storing it to the underlying database. For bean-managed persistence, the EJB provider should code at this location the JDBC statements for writing the data in the database. For entity beans with container-managed persistence, this method should only contain some "pre-store statements," since the container will extract the container-managed fields and write them to the database just after the ejbStore method call.

### Example

The following examples are for container-managed persistence with EJB 1.1 and EJB 2.0. For bean-managed persistence, refer to the examples delivered with your specific platform.

CMP 1.1

    package eb;

    import java.rmi.RemoteException;
    import javax.ejb.EntityBean;
    import javax.ejb.EntityContext;
    import javax.ejb.ObjectNotFoundException;
    import javax.ejb.RemoveException;
    import javax.ejb.EJBException;

    public class AccountImplBean implements EntityBean {

        // Keep the reference on the EntityContext
        protected EntityContext entityContext;

        // Object state
        public Integer accno;
        public String customer;
        public double balance;

        public Integer ejbCreate(int val_accno, String val_customer, double val_balance) {

            // Init object state
            accno = new Integer(val_accno);
            customer = val_customer;
            balance = val_balance;
            return null;
        }

        public void ejbPostCreate(int val_accno, String val_customer, double val_balance) {
            // Nothing to be done for this simple example.
        }

        public void ejbActivate() {
            // Nothing to be done for this simple example.
        }

        public void ejbLoad() {
            // Nothing to be done for this simple example, in implicit persistence.
        }

        public void ejbPassivate() {
            // Nothing to be done for this simple example.
        }

        public void ejbRemove() {
            // Nothing to be done for this simple example, in implicit persistence.
        }

        public void ejbStore() {
            // Nothing to be done for this simple example, in implicit persistence.
        }

        public void setEntityContext(EntityContext ctx) {
            // Keep the entity context in object
            entityContext = ctx;
        }

        public void unsetEntityContext() {
            entityContext = null;
        }

        public double getBalance() {
            return balance;
        }

        public void setBalance(double d) {
            balance = balance + d;
        }

        public String  getCustomer() {
            return customer;
        }

        public void setCustomer(String c) {
            customer = c;
        }

        public int getNumber()  {
            return accno.intValue();
        }
    }

CMP 2.0

    import java.rmi.RemoteException;
    import javax.ejb.EntityBean;
    import javax.ejb.EntityContext;
    import javax.ejb.ObjectNotFoundException;
    import javax.ejb.RemoveException;
    import javax.ejb.CreateException;
    import javax.ejb.EJBException;

    public abstract class AccountImpl2Bean implements EntityBean {

        // Keep the reference on the EntityContext
        protected EntityContext entityContext;

        /*========================= Abstract set and get accessors for cmp fields ==============*/

        public abstract String getCustomer();
        public abstract void setCustomer(String customer);

        public abstract double getBalance();
        public abstract void setBalance(double balance);

        public abstract int getAccno();
        public abstract void setAccno(int accno);

        /*========================= ejbCreate methods ============================*/

        public Integer ejbCreate(int val_accno, String val_customer, double val_balance)
            throws CreateException {

            // Init object state
            setAccno(val_accno);
            setCustomer(val_customer);
            setBalance(val_balance);
            return null;
        }

        public void ejbPostCreate(int val_accno, String val_customer, double val_balance) {
            // Nothing to be done for this simple example.
        }

        /*====================== javax.ejb.EntityBean implementation =================*/

        public void ejbActivate() {
            // Nothing to be done for this simple example.
        }

        public void ejbLoad() {
            // Nothing to be done for this simple example, in implicit persistence.
        }

        public void ejbPassivate() {
            // Nothing to be done for this simple example.
        }

        public void ejbRemove() throws RemoveException {
            // Nothing to be done for this simple example, in implicit persistence.
        }

        public void ejbStore() {
            // Nothing to be done for this simple example, in implicit persistence.
        }

        public void setEntityContext(EntityContext ctx) {

            // Keep the entity context in object
            entityContext = ctx;
        }

        public void unsetEntityContext()  {
            entityContext = null;
        }

        /**
         * Business method to get the Account number
         */
        public int getNumber()  {
            return getAccno();
        }

    }

## Writing Database Access Operations (bean-managed persistence)

For bean-managed persistence, data access operations are developed by the bean provider using the JDBC interface. However, getting database connections must be obtained through the javax.sql.DataSource interface on a datasource object provided by the EJB platform. This is mandatory since the EJB platform is responsible for managing the connection pool and for transaction management. Thus, to get a JDBC connection, in each method performing database operations, the bean provider must:

- call the getConnection(...) method of the DataSource object, to obtain a connection to perform the JDBC operations in the current transactional context (if there are JDBC operations),
- call the close() method on this connection after the database access operations, so that the connection can be returned to the connection pool (and be dissociated from the potential current transaction).

A method that performs database access must always contain the getConnection and close statements, as follows:

    public void doSomethingInDB (...) {
        conn = dataSource.getConnection();
        ... // Database access operations
        conn.close();
    }

A DataSource object associates a JDBC driver with a database (as an ODBC datasource). It is created and registered in JNDI by the EJB server at launch time (refer also to the section "JDBC DataSources configuration").

A DataSource object is a resource manager connection factory for `java.sql.Connection` objects, which implements connections to a database management system. The enterprise bean code refers to resource factories using logical names called "Resource manager connection factory references." The resource manager connection factory references are special entries in the enterprise bean environment. The bean provider must use resource manager connection factory references to obtain the datasource object as follow:

- Declare the resource reference in the standard deployment descriptor using a `resource-ref` element.
- Lookup the datasource in the enterprise bean environment using the JNDI interface (refer to the section "Enterprise Bean's Environment").

The deployer binds the resource manager connection factory references to the actual resource factories that are configured in the server. This binding is done in the JOnAS-specific deployment descriptor using the jonas-resource element.

### Example

The declaration of the resource reference in the standard deployment descriptor looks like the following:

    <resource-ref>
    <res-ref-name>jdbc/AccountExplDs</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
    </resource-ref>

The <res-auth> element indicates which of the two resource manager authentication approaches is used:

- Container: the deployer sets up the sign-on information.
- Bean: the bean programmer should use the getConnection method with user and password parameters.

The JOnAS-specific deployment descriptor must map the environment JNDI name of the resource to the actual JNDI name of the resource object managed by the EJB server. This is done in the <jonas-resource> element.

      <jonas-entity>
        <ejb-name>AccountExpl</ejb-name>
        <jndi-name>AccountExplHome</jndi-name>
        <jonas-resource>
          <res-ref-name>jdbc/AccountExplDs</res-ref-name>
          <jndi-name>jdbc_1</jndi-name>
        </jonas-resource>
      </jonas-entity>

The ejbStore method of the same Account example with bean-managed persistence is shown in the following example. It performs JDBC operations to update the database record representing the state of the entity bean instance. The JDBC connection is obtained from the datasource associated with the bean. This datasource has been instantiated by the EJB server and is available for the bean through its resource reference name, which is defined in the standard deployment descriptor.

In the bean, a reference to a datasource object of the EJB server is initialized:

`it = new InitialContext();`

`ds = (DataSource)it.lookup("java:comp/env/jdbc/AccountExplDs");`

Then, this datasource object is used in the implementation of the methods performing JDBC operations, such as ejbStore, as illustrated in the following:

    public void ejbStore
        Connection conn = null;
        PreparedStatement stmt = null;
        try { // get a connection
            conn = ds.getConnection();
            // store Object state in DB
            stmt = conn.prepareStatement("update account set customer=?,balance=? where accno=?");
            stmt.setString(1, customer);
            stmt.setDouble(2, balance);
            Integer pk = (Integer)entityContext.getPrimaryKey();
            stmt.setInt(3, pk.accno);
            stmt.executeUpdate();
         } catch (SQLException e) {
            throw new javax.ejb.EJBException("Failed to store bean to database", e);
         } finally {
            try {
                if (stmt != null) stmt.close();    // close statement
                if (conn != null) conn.close();    // release connection
            } catch (Exception ignore) {}
         }
    }

Note that the close statement instruction may be important if the server is intensively accessed by many clients performing entity bean access. If the statement is not closed in the finally block, since stmt is in the scope of the method, it will be deleted at the end of the method (and the close will be implicitly done). However, it may be some time before the Java garbage collector deletes the statement object. Therefore, if the number of clients performing entity bean access is important, the DBMS may raise a "too many opened cursors" exception (a JDBC statement corresponds to a DBMS cursor). Since connection pooling is performed by the platform, closing the connection will not result in a physical connection close, therefore opened cursors will not be closed. Thus, it is preferable to explicitly close the statement in the method.

It is a good programming practice to put the JDBC connection and JDBC statement close operations in a finally bloc of the try statement.

## Configuring Database Access for Container-managed Persistence

The standard way to indicate to an EJB platform that an entity bean has container-managed persistence is to fill the `<persistence-type>` tag of the deployment descriptor with the value "container," and to fill the `<cmp-field>` tag of the deployment descriptor with the list of container-managed fields (the fields that the container will have in charge to make persistent). The CMP version (1.x or 2.x) should also be specified in the <cmp-version> tag. In the textual format of the deployment descriptor, this is represented by the following lines:

        <persistence-type>container</persistence-type>
        <cmp-version>1.x</cmp-version>
        <cmp-field>
          <field-name>fieldOne</field-name>
        </cmp-field>
        <cmp-field>
          <field-name>fieldTwo</field-name>
        </cmp-field>

With container-managed persistence the programmer need not develop the code for accessing the data in the relational database; this code is included in the container itself (generated by the platform tools). However, for the EJB platform to know how to access the database and which data to read and write in the database, two types of information must be provided with the bean:

- First, the container must know which database to access and how to access it. To do this, the only required information is the name of the DataSource that will be used to get the JDBC connection. For container-managed persistence, only one DataSource per bean should be used.
- Then, it is necessary to know the mapping of the bean fields to the underlying database (which table, which column). For CMP 1.1 or CMP 2.0, this mapping is specified by the deployer in the JOnAS-specific deployment descriptor. Note that for CMP 2.0, this mapping may be entirely generated by JOnAS.

The EJB specification does not specify how this information should be provided to the EJB platform by the bean deployer. Therefore, what is described in the remainder of this section is specific to JOnAS.

For CMP 1.1, the bean deployer is responsible for defining the mapping of the bean fields to the database table columns. The name of the DataSource can be set at deployment time, since it depends on the EJB platform configuration. This database configuration information is defined in the JOnAS-specific deployment descriptor via the `jdbc-mapping` element. The following example defines the mapping for a CMP 1.1 entity bean:

        <jdbc-mapping>
          <jndi-name>jdbc_1</jndi-name>
          <jdbc-table-name>accountsample</jdbc-table-name>
          <cmp-field-jdbc-mapping>
          <field-name>mAccno</field-name>
          <jdbc-field-name>accno</jdbc-field-name>
          </cmp-field-jdbc-mapping>
          <cmp-field-jdbc-mapping>
          <field-name>mCustomer</field-name>
          <jdbc-field-name>customer</jdbc-field-name>
          </cmp-field-jdbc-mapping>
          <cmp-field-jdbc-mapping>
          <field-name>mBalance</field-name>
          <jdbc-field-name>balance</jdbc-field-name>
        </jdbc-mapping>

`jdbc_1` is the JNDI name of the DataSource object identifying the database. `accountsample` is the name of the table used to store the bean instances in the database. `mAccno`, `mCustomer`, and `mBalance` are the names of the container-managed fields of the bean to be stored in the `accno`, `customer`, and `balance` columns of the `accountsample` table. This example applies to container-managed persistence. For bean-managed persistence, the database mapping does not exist.

For a CMP 2.0 entity bean, only the `jndi-name` element of the `jdbc-mapping` is mandatory, since the mapping may be generated automatically (for an explicit mapping definition, refer to the "JOnAS Database Mapping" section of the Using CMP2.0 persistence chapter):

        <jdbc-mapping>
          <jndi-name>jdbc_1</jndi-name>
        </jdbc-mapping>
        <cleanup>create</cleanup>

For a CMP 2.0 entity bean, the JOnAS-specific deployment descriptor contains an additional element, `cleanup`, at the same level as the `jdbc-mapping` element, which can have one of the following values:

`removedata`
  at bean loading time, the content of the tables storing the bean data is deleted
`removeall`
  at bean loading time, the tables storing the bean data are dropped (if they exist) and created
`none`
  do nothing
`create`
  default value (if the element is not specified), at bean loading time, the tables for storing the bean data are created if they do not exist

For CMP 1.1, the `jdbc-mapping` element can also contain information defining the behaviour of the implementation of a find<method> method (i.e. the ejbFind<method> method, that will be generated by the platform tools). This information is represented by the `finder-method-jdbc-mapping` element.

For each finder method, this element provides a way to define an SQL WHERE clause that will be used in the generated finder method implementation to query the relational table storing the bean entities. Note that the table column names should be used, not the bean field names. Example:

          <finder-method-jdbc-mapping>
            <jonas-method>
              <method-name>findLargeAccounts</method-name>
            </jonas-method>
            <jdbc-where-clause>where balance &gt; ?</jdbc-where-clause>
          </finder-method-jdbc-mapping>

The previous finder method description will cause the platform tools to generate an implementation of ejbFindLargeAccount(double arg) that returns the primary keys of the entity bean objects corresponding to the tuples returned by the "select ... from Account where balance > ?", where '?' will be replaced by the value of the first argument of the findLargeAccount method. If several '?' characters appear in the provided WHERE clause, this means that the finder method has several arguments and the '?' characters will correspond to these arguments, adhering to the order of the method signature.

In the WHERE clause, the parameters can be followed by a number, which specifies the method parameter number that will be used by the query in this position.
Example: The WHERE clause of the following finder method can be:

          Enumeration findByTextAndDateCondition(String text, java.sql.Date date)

          WHERE (description like ?1 OR summary like ?1) AND (?2 &gt; date)

Note that a `<finder-method-jdbc-mapping>` element for the findByPrimaryKey method is not necessary, since the meaning of this method is known.

Additionally, note that for CMP 2.0, the information defining the behaviour of the implementation of a find<method> method is located in the standard deployment descriptor, as an EJB-QL query (i.e. this is not JOnAS-specific information). The same finder method example in CMP 2.0:

          <query>
            <query-method>
              <method-name>findLargeAccounts</method-name>
              <method-params>
                  <method-param>double</method-param>
              </method-params>
            </query-method>
            <ejb-ql>SELECT OBJECT(o) FROM accountsample o WHERE o.balance &gt; ?1</ejb-ql>
          </query>

The datatypes supported for container-managed fields in CMP 1.1 are the following:

Java Type | JDBC Type | JDBC driver Access methods
boolean | BIT | getBoolean(), setBoolean()
byte | TINYINT | getByte(), setByte()
short | SMALLINT | getShort(), setShort()
int | INTEGER | getInt(), setInt()
long | BIGINT | getLong(), setLong()
float | FLOAT | getFloat(), setFloat()
double | DOUBLE | getDouble(), setDouble
byte[] | VARBINARY or LONGVARBINARY (1) | getBytes(), setBytes()
java.lang.String | VARCHAR or LONGVARCHAR (1) | getString(), setString()
java.lang.Boolean | BIT | getBoolean(), setObject()
java.lang.Integer | INTEGER | getInt(), setObject()
java.lang.Short | SMALLINT | getShort(), setObject()
java.lang.Long | BIGINT | getLong(), setObject()
java.lang.Float | REAL | getFloat(), setObject()
java.lang.Double | DOUBLE | getDouble(), setObject()
java.math.BigDecimal | NUMERIC | getBigDecimal(), setObject()
java.math.BigInteger | NUMERIC | getBigDecimal(), setObject()
java.sql.Date | DATE | getDate(), setDate()
java.sql.Time | TIME | getTime(), setTime()
java.sql.Timestamp | TIMESTAMP | getTimestamp(), setTimestamp()
any serializable class | VARBINARY or LONGVARBINARY (1) | getBytes(), setBytes()

(1) The mapping for String will normally be VARCHAR, but will turn into LONGVARCHAR if the given value exceeds the driver's limit on VARCHAR values. The case is similar for byte[] and VARBINARY and LONGVARBINARY values.

For CMP 2.0, the supported datatypes depend on the JORM mapper used.

## Tuning Container for Entity Bean Optimizations

JOnAS must make a compromise between scalability and performance. For that reason, several tags in the JOnAS-specific deployment descriptor have been introduced. For most applications, there is no need to change the default values for all these tags. See `$JONAS_ROOT/xml/jonas-ejb-jar_4_7.xsd` for a complete description of the JOnAS-specific deployment descriptor.

Note that if several of these elements are used, they should appear in the following order within the <jonas-entity> element:

1. is-modified-method-name
2. passivation-timeout
3. read-timeout
4. max-wait-time
5. inactivity-timeout
6. deadlock-timeout
7. shared
8. prefetch
9. hard-limit
10. max-cache-size
11. min-pool-size
12. cleanup
13. lock-policy

### lock-policy

The JOnAS ejb container is able to manage seven different lock-policies:

container-serialized (default)
  The container ensures the transaction serialization. This policy is suitable for entity beans having non transacted methods that can modify the bean state. It works only if the bean is accessed from 1 jonas server (shared = false).
container-serialized-transacted
  The container ensures the transaction serialization. This policy is suitable for most entity beans.
container-read-committed
  This policy is similar to container-serialized-transacted, except that accesses outside transaction do not interfere with transactional accesses. This can help to avoid deadlocks in certain cases, when accessing a bean concurrently with and without a transactional context. The only drawback of this policy is that it consumes more memory (2 instances instead of 1).
container-read-uncommitted (deprecated)
  All methods share the same instance (like container-serialized), but there is no synchronization. For example, this policy is of interest for read-only entity beans, or if the bean instances are very rarely modified. It will fail if two or more threads try to modify the same instance concurrently. This policy is deprecated because it can be replaced by `container-read-write`.
database
  Allow the database to handle the transaction isolation. With this policy, it is possible to choose the transaction isolation in a database. This may be of interest for applications that heavily use transactional read-only operations, or when the flag shared is needed. It does not work with all databases and is not memory efficient.
read-only
  The bean state is never written to the database. If the bean is `shared`, the bean state is read from the database regularly. Use the `read-timeout` tag to specify the timeout value.
container-read-write
  All methods share the same instance (like container-serialized). A synchronization is done only when the instance is modified. No lock is taken while the instance is read only. This policy does not work if the bean is `shared`, nor does it work for CMP 1.x beans.

Important: If CMP1 beans are deployed, only the following policies should be used:

- container-serialized
- container-serialized-transacted
- read-only
- container-read-committed
- database, but only with shared=true.

### shared

This flag will be defined as `true` if the bean persistent state can be accessed outside the JOnAS Server. When this flag is `false`, the JOnAS Server can do some optimization, such as not re-reading the bean state before starting a new transaction. The default value depends on the lock-policy:

- `false` for `container-serialized`, `container-read-uncommitted` or `container-read-write`. For these 3 policies, shared=false is mandatory.
- `true` in the other cases.

Lock policy `database` works only if shared=true.

### prefetch

This is a CMP2-specific option. The default is false. This can be set to true if it is desirable to have a cache managed after finder methods execution, in order to optimize further accesses inside the same transaction.

Important note:

- The prefetch will not be used for methods that have no transactional context.
- It is impossible to set the prefetch option if the lock policy is container-read-uncommitted.

### max-cache-size / hard-limit / max-wait-time

This optional integer value represents the maximum number of instances in memory. The purpose of this value is to keep JOnAS scalable. The default value is "no limit". To save memory, this value should be set very low if it is known that instances will not be reused. Depending on whether `hard-limit` value is `true` or `false`, this `max-cache-size` value will be overtaken or not: In the case of `hard-limit` = `true`, the container will never allocate more instances than the `max-cache-size` value. When the limit is reached, the thread will be set to waiting until instances are released. It is possible to specify the maximum time to wait for an instance with the tag `max-wait-time`. The default is 0, which means "no wait".

### min-pool-size

This optional integer value represents the number of instances that will be created in the pool when the bean is loaded. This will improve bean instance create time, at least for the first instances. The default value is 0. When passivation occurs, for example if there are too many instances in memory, instances are released and placed in the pool only if min-pool-size is not reached. The intent is to try to keep at least min-pool-size instances in the pool of available instances.

### is-modified-method-name

To improve performance of CMP 1.1 entity beans, JOnAS implements the isModified extension. Before performing an update, the container calls a method of the bean whose name is identified in the `is-modified-method-name` element of the JOnAS-specific deployment descriptor. This method is responsible for determining if the state of the bean has been changed. By doing this, the container determines if it must store data in the database or not.

Note that this is useless with CMP2 entity beans, since this will be done automatically by the container.

#### Example

The bean implementation manages a boolean `isDirty` and implements a method that returns the value of this boolean: `isModified`

        private transient boolean isDirty;
        public boolean isModified() {
            return isDirty;
        }

The JOnAS-specific deployment descriptor directs the bean to implement an `isModified` method:

        <jonas-entity>
          <ejb-name>Item</ejb-name>
          <is-modified-method-name>isModified</is-modified-method-name>
          .....
        </jonas-entity>

Methods that modify the value of the bean must set the flag `isDirty` to `true`.
Methods that restore the value of the bean from the database must reset the flag `isDirty` to `false`. Therefore, the flag must be set to `false` in the `ejbLoad()` and `ejbStore()` methods.

### passivation-timeout

This flag is used only when lock-policy = container-serialized. When instances are accessed outside of any transaction, their state is kept in memory to improve performance. However, a passivation will occur in three situations:

1. When the bean is unloaded from the server, at least when the server is stopped.
2. When a transaction is started on this instance.
3. After a configurable timeout: passivation-timeout. If the bean is always accessed with no transaction, it may be prudent to periodically store the bean state on disk.

This passivation timeout can be configured in the JOnAS-specific deployment descriptor, with the non-mandatory tag <passivation-timeout>. Example:

        <jonas-entity>
          <ejb-name>Item</ejb-name>
          <passivation-timeout>5</passivation-timeout>
          .....
        </jonas-entity>

This entity bean will be passivated every five second, if not accessed within transactions.

### read-timeout

This flag is used only when lock-policy = read-only. In case shared=true has been set, it is important to synchronize the bean state by reading it periodically from the storage. This is configurable with the read-timeout flag. Value is in seconds.

### inactivity-timeout

Bean passivation sends the state of the bean to persistent storage and removes from memory only the bean instance objects that are holding this state. All container objects handling bean access (remote object, interceptors, ...) are kept in memory so that future access will work, requiring only a reload operation (getting the state). It may be advantageous to conserve more memory and completely remove the bean instance from memory; this can be achieved through the <inactivity-timeout> element. This element is used to save memory when a bean has not been used for a long period of time. If the bean has not been used after the specified time (in seconds), all its container objects are removed from the server. If a client has kept a reference on a remote object and tries to use it, then the client will receive an exception.

## Using CMP2.0 persistence

This section highlights the main differences between CMP as defined in EJB 2.0 specification (called CMP2.0) and CMP as defined in EJB 1.1 specification (called CMP1.1). Major new features in the standard development and deployment of CMP2.0 entity beans are listed (comparing them to CMP1.1), along with JOnAS-specific information. Mapping CMP2.0 entity beans to the database is described in detail. Note that the database mapping can be created entirely by JOnAS, in which case the JOnAS-specific deployment descriptor for an entity bean should contain only the datasource and the element indicating how the database should be initialized.

### Standard CMP2.0 Aspects

This section briefly describes the new features available in CMP2.0 as compared to CMP 1.1, and how these features change the development of entity beans.

#### Entity Bean Implementation Class

The EJB implementation class 1) implements the bean's business methods of the component interface, 2) implements the methods dedicated to the EJB environment (the interface of which is explicitly defined in the EJB specification), and 3) defines the abstract methods representing both the persistent fields (cmp-fields) and the relationship fields (cmr-fields). The class must implement the `javax.ejb.EntityBean` interface, be defined as public, and be abstract (which is not the case for CMP1.1, where it must not be abstract). The abstract methods are the get and set accessor methods of the bean cmp and cmr fields. Refer to the examples and details in the section "Developing Entity Beans" of the JOnAS documentation.

#### Standard Deployment Descriptor

The standard way to indicate to an EJB platform that an entity bean has container-managed persistence is to fill the `<persistence-type>` tag of the deployment descriptor with the value "container," and to fill the `<cmp-field>` tags of the deployment descriptor with the list of container-managed fields (the fields that the container will have in charge to make persistent) and the `<cmr-field>` tags identifying the relationships. The CMP version (1.x or 2.x) should also be specified in the <cmp-version> tag. This is represented by the following lines in the deployment descriptor:

        <persistence-type>container</persistence-type>
        <cmp-version>1.x</cmp-version>
        <cmp-field>
          <field-name>fieldOne</field-name>
        </cmp-field>
        <cmp-field>
          <field-name>fieldTwo</field-name>
        </cmp-field>

Note that for running CMP1.1-defined entity beans on an EJB2.0 platform, such as JOnAS 3.x, you must introduce this <cmp-version> element in your deployment descriptors, since the default cmp-version value (if not specified) is 2.x.

Note that for CMP 2.0, the information defining the behaviour of the implementation of a find<method> method is located in the standard deployment descriptor as an EJB-QL query (this is not JOnAS-specific information). For CMP 1.1, this information is located in the JOnAS-specific deployment descriptor as an SQL WHERE clause specified in a <finder-method-jdbc-mapping> element.

Finder method example in CMP 2.0: for a `findLargeAccounts(double val)` method defined on the Account entity bean of the JOnAS eb example.

          <query>
            <query-method>
              <method-name>findLargeAccounts</method-name>
              <method-params>
                  <method-param>double</method-param>
              </method-params>
            </query-method>
            <ejb-ql>SELECT OBJECT(o) FROM accountsample o WHERE o.balance &gt; ?1</ejb-ql>
          </query>

### JOnAS EJBQL extension

#### LIMIT clause

The LIMIT feature has been added to the standard EJBQL query language. This feature enables you to retrieve just a portion of the results generated by the rest of a query.

The syntax of the LIMIT clause is:

        limit_clause ::= LIMIT limit_expression (, limit_expression )?
        limit_expression ::= integer_literal | input_parameter

The first limit_expression corresponds to the start_at range and the second one to the size range.

The limit_clause is the last clause of the query:

        ejbql ::= select_clause from_clause [where_clause] [orderby_clause] [limit_clause]

Example:

        SELECT OBJECT(c) FROM jt2_Customer AS c ORDER BY c.id LIMIT ?1, 20

Note that this feature is currently not implemented on all the database types supported by JORM/MEDOR.

### JOnAS Database mappers

For implementing the EJB 2.0 persistence (CMP2.0), JOnAS relies on the JORM framework. JORM itself relies on JOnAS DataSources (specified in DataSource properties files) for connecting to the actual database. JORM must adapt its object-relational mapping to the underlying database, for which it makes use of adapters called "mappers." Thus, for each type of database (and more precisely for each JDBC driver), the corresponding mapper must be specified in the DataSource. This is the purpose of the datasource.mapper property of the DataSource properties file. Note that all JOnAS-provided DataSource properties files (in JOnAS_ROOT/conf) already contain this property with the correct mapper.

property name | description | possible values
--- | --- | ---

datasource.mapper

JORM database mapper

- `rdb`: generic mapper (JDBC standard driver ...)
- `rdb.cloudscape`: Cloudscape
- `rdb.db2`: DB2
- `rdb.firebird`: Firebird
- `rdb.hsql`: HSQL
- `rdb.mckoi`: McKoi Db
- `rdb.mysql`: MySQL
- `rdb.oracle8`: Oracle 8 and lesser versions
- `rdb.oracle`: Oracle 9
- `rdb.postgres`: PostgreSQL (>= 7.2)
- `rdb.sapdb`: Sap DB
- `rdb.sqlserver`: MS Sql Server
- `rdb.sybase`: Sybase

Contact the JOnAS team to obtain a mapper for other databases.

The container code generated at deployment is now independent of the JORM mappers. Until JOnAS 4.1.4, the container code generated at deployment (GenIC or ejbjar ant task) was dependent on this mapper. It was possible to deploy (generate container code) a bean for several mappers in order to change the database (i.e. the DataSource file) without redeploying the bean. These mappers were specified as the mappernames argument of the GenIC command or as the mappernames attribute of the JOnAS ANT ejbjar task. The value was a comma-separated list of mapper names for which the container classes were generated. These mappernames options are now deprecated.

### JOnAS Database Mapping (Specific Deployment Descriptor)

The mapping to the database of entity beans and their relationships may be specified in the JOnAS-specific deployment descriptor, in `jonas-entity` elements, and in `jonas-ejb-relation` elements. Since JOnAS is able to generate the database mapping, all the elements of the JOnAS-specific deployment descriptor defined in this section (which are sub-elements of `jonas-entity` or `jonas-ejb-relation`) are optional, except those for specifying the datasource and the initialization mode (i.e. the `jndi-name` of `jdbc-mapping` and `cleanup`). The default values of these mapping elements, provided in this section, define the JOnAS-generated database mapping.

#### Specifying and Initializing the Database

For specifying the database within which a CMP 2.0 entity bean is stored, the `jndi-name` element of the `jdbc-mapping` is necessary. This is the JNDI name of the DataSource representing the database storing the entity bean.

        <jdbc-mapping>
          <jndi-name>jdbc_1</jndi-name>
        </jdbc-mapping>

For a CMP 2.0 entity bean, the JOnAS-specific deployment descriptor contains an additional element, `cleanup`, to be specified before the `jdbc-mapping` element, which can have one of the following values:

`removedata`
  at bean loading time, the content of the tables storing the bean data is deleted
`removeall`
  at bean loading time, the tables storing the bean data are dropped (if they exist) and created
`none`
  do nothing
`create`
  default value (if the element is not specified), at bean loading time, the tables for storing the bean data are created if they do not exist.

It may be useful for testing purposes to delete the database data each time a bean is loaded. For this purpose, the part of the JOnAS-specific deployment descriptor related to the entity bean may look like the following:

        <cleanup>removedata</cleanup>
        <jdbc-mapping>
          <jndi-name>jdbc_1</jndi-name>
        </jdbc-mapping>

#### CMP fields Mapping

Mapping CMP fields in CMP2.0 is similar to that of CMP 1.1, but in CMP2.0 it is also possible to specify the SQL type of a column. Usually this SQL type is used if JOnAS creates the table (`create` value of the `cleanup` element), and if the JORM default chosen SQL type is not appropriate.

###### Standard Deployment Descriptor

        .....
        <entity>
          <ejb-name>A</ejb-name>
          .....
          <cmp-field>
            <field-name>idA</field-name>
          </cmp-field>
          <cmp-field>
            <field-name>f</field-name>
          </cmp-field>
        .....
        </entity>
        .....

###### Database Mapping

t_A |
c_idA | c_f
... | ...

###### JOnAS Deployment Descriptor

        .....
        <jonas-entity>
          <ejb-name>A</ejb-name>
          .....
          <jdbc-mapping>
            <jndi-name>jdbc_1</jndi-name>
            <jdbc-table-name>t_A</jdbc-table-name>
            <cmp-field-jdbc-mapping>
              <field-name>idA</field-name>
              <jdbc-field-name>c_idA</jdbc-field-name>
            </cmp-field-jdbc-mapping>
            <cmp-field-jdbc-mapping>
              <field-name>f</field-name>
              <jdbc-field-name>c_f</jdbc-field-name>
              <sql-type>varchar(40)</sql-type>
            </cmp-field-jdbc-mapping>
          </jdbc-mapping>
          .....
        </jonas-entity>
        .....

Defaults values:

jndi-name | Mandatory
jdbc-table-name | Optional. Default value is the upper-case CMP2 abstract-schema-name, or the CMP1 ejb-name, suffixed by _.
cmp-field-jdbc-mapping | Optional.
jdbc-field-name | Optional. Default value is the field-name suffixed by _. idA_ and f_ in the example.
sql-type | Optional. Default value defined by JORM.

#### CMR fields Mapping to primary-key-fields (simple pk)

##### 1-1 unidirectional relationships

###### Standard Deployment Descriptor

        .....
        <entity>
          <ejb-name>A</ejb-name>
          .....
          <cmp-field>
            <field-name>idA</field-name>
          </cmp-field>
          <primkey-field>idA</primkey-field>
          .....
        </entity>
        .....
        <entity>
          <ejb-name>B</ejb-name>
          .....
          <cmp-field>
            <field-name>idB</field-name>
          </cmp-field>
          <primkey-field>idB</primkey-field>
          .....
        </entity>
        .....
        <relationships>
          <ejb-relation>
            <ejb-relation-name>a-b</ejb-relation-name>
            <ejb-relationship-role>
              <!-- A => B -->
                    <ejb-relationship-role-name>a2b</ejb-relationship-role-name>
              <multiplicity>One</multiplicity>
              <relationship-role-source>
                <ejb-name>A</ejb-name>
              </relationship-role-source>
              <cmr-field>
                <cmr-field-name>b</cmr-field-name>
              </cmr-field>
            </ejb-relationship-role>
            <ejb-relationship-role>
              <!-- B => A -->
              <ejb-relationship-role-name>b2a</ejb-relationship-role-name>
              <multiplicity>One</multiplicity>
              <relationship-role-source>
                <ejb-name>B</ejb-name>
              </relationship-role-source>
            </ejb-relationship-role>
          </ejb-relation>
        </relationships>
        .....

###### Database Mapping

t_A |
c_idA | cfk_idB
... | ...

t_B
c_idB
...

There is a foreign key in the table of the bean that owns the CMR field.

###### JOnAS Deployment Descriptor

        .....
        <jonas-entity>
          <ejb-name>A</ejb-name>
          .....
          <jdbc-mapping>
            <jndi-name>jdbc_1</jndi-name>
            <jdbc-table-name>t_A/jdbc-table-name>
            <cmp-field-jdbc-mapping>
              <field-name>idA</field-name>
              <jdbc-field-name>c_idA</jdbc-field-name>
            </cmp-field-jdbc-mapping>
          </jdbc-mapping>
          .....
        </jonas-entity>
        .....
        <jonas-entity>
          <ejb-name>B</ejb-name>
          .....
          <jdbc-mapping>
            <jndi-name>jdbc_1</jndi-name>
            <jdbc-table-name>t_B/jdbc-table-name>
            <cmp-field-jdbc-mapping>
              <field-name>idB</field-name>
              <jdbc-field-name>c_idB</jdbc-field-name>
            </cmp-field-jdbc-mapping>
          </jdbc-mapping>
          .....
        </jonas-entity>
        .....
        <jonas-ejb-relation>
          <ejb-relation-name>a-b</ejb-relation-name>
          <jonas-ejb-relationship-role>
            <ejb-relationship-role-name>a2b</ejb-relationship-role-name>
            <foreign-key-jdbc-mapping>
              <foreign-key-jdbc-name>cfk_idb</foreign-key-jdbc-name>
            </foreign-key-jdbc-mapping>
          </jonas-ejb-relationship-role>
        </jonas-ejb-relation>
        .....

foreign-key-jdbc-name is the column name of the foreign key in the table of the source bean of the relationship-role.
In this example, where the destination bean has a primary-key-field, it is possible to deduce that this foreign-key-jdbc-name column is to be associated with the column of this primary-key-field in the table of the destination bean.

Default values:

jonas-ejb-relation | Optional
foreign-key-jdbc-name | Optional. Default value is the abstract-schema-name of the destination bean, suffixed by _, and by its primary-key-field. B_idb in the example.

##### 1-1 bidirectional relationships

Compared to 1-1 unidirectional relationships, there is a CMR field in both of the beans, thus making two types of mapping possible.

###### Standard Deployment Descriptor

        .....
        <relationships>
          <ejb-relation>
            <ejb-relation-name>a-b</ejb-relation-name>
            <ejb-relationship-role>
              <!-- A => B -->
                    <ejb-relationship-role-name>a2b</ejb-relationship-role-name>
              <multiplicity>One</multiplicity>
              <relationship-role-source>
                <ejb-name>A</ejb-name>
              </relationship-role-source>
              <cmr-field>
                <cmr-field-name>b</cmr-field-name>
              </cmr-field>
            </ejb-relationship-role>
            <ejb-relationship-role>
              <!-- B => A -->
              <ejb-relationship-role-name>b2a</ejb-relationship-role-name>
              <multiplicity>One</multiplicity>
              <relationship-role-source>
                <ejb-name>B</ejb-name>
              </relationship-role-source>
              <cmr-field>
                <cmr-field-name>a</cmr-field-name>
              </cmr-field>
            </ejb-relationship-role>
          </ejb-relation>
        </relationships>
        .....

###### Database Mapping

Two mappings are possible. One of the tables may hold a foreign key.

Case 1:

t_A |
c_idA | cfk_idB
... | ...

t_B
c_idB
...

Case 2:

t_A
c_idA
...

t_B |
c_idB | cfk_idA
... | ...

###### JOnAS Deployment Descriptor

Case 1:

        .....
        <jonas-ejb-relation>
          <ejb-relation-name>a-b</ejb-relation-name>
          <jonas-ejb-relationship-role>
            <ejb-relationship-role-name>a2b</ejb-relationship-role-name>
            <foreign-key-jdbc-mapping>
              <foreign-key-jdbc-name>cfk_idb</foreign-key-jdbc-name>
            </foreign-key-jdbc-mapping>
          </jonas-ejb-relationship-role>
        </jonas-ejb-relation>
        .....

Case 2:

        .....
        <jonas-ejb-relation>
          <ejb-relation-name>a-b</ejb-relation-name>
          <jonas-ejb-relationship-role>
            <ejb-relationship-role-name>b2a</ejb-relationship-role-name>
            <foreign-key-jdbc-mapping>
              <foreign-key-jdbc-name>cfk_ida</foreign-key-jdbc-name>
            </foreign-key-jdbc-mapping>
          </jonas-ejb-relationship-role>
        </jonas-ejb-relation>
        .....

For the default mapping, the foreign key is in the table of the source bean of the first ejb-relationship-role of the ejb-relation. In the example, the default mapping corresponds to case 1, since the ejb-relationship-role a2b is the first defined in the ejb-relation a-b. Then, the default values are similar to those of the 1-1 unidirectional relationship.

##### 1-N unidirectional relationships

###### Standard Deployment Descriptor

        .....
        <relationships>
          <ejb-relation>
            <ejb-relation-name>a-b</ejb-relation-name>
            <ejb-relationship-role>
              <!-- A => B -->
                    <ejb-relationship-role-name>a2b</ejb-relationship-role-name>
              <multiplicity>One</multiplicity>
              <relationship-role-source>
                <ejb-name>A</ejb-name>
              </relationship-role-source>
              <cmr-field>
                <cmr-field-name>b</cmr-field-name>
                <cmr-field-type>java.util.Collection</cmr-field-type>
              </cmr-field>
            </ejb-relationship-role>
            <ejb-relationship-role>
              <!-- B => A -->
              <ejb-relationship-role-name>b2a</ejb-relationship-role-name>
              <multiplicity>Many</multiplicity>
              <relationship-role-source>
                <ejb-name>B</ejb-name>
              </relationship-role-source>
            </ejb-relationship-role>
          </ejb-relation>
        </relationships>
        .....

###### Database Mapping

t_A
c_idA
...

t_B |
c_idB | cfk_idA
... | ...

In this case, the foreign key must be in the table of the bean which is on the "many" side of the relationship (i.e. in the table of the source bean of the relationship role with multiplicity many), t_B.

###### JOnAS Deployment Descriptor

        .....
        <jonas-ejb-relation>
          <ejb-relation-name>a-b</ejb-relation-name>
          <jonas-ejb-relationship-role>
            <ejb-relationship-role-name>b2a</ejb-relationship-role-name>
            <foreign-key-jdbc-mapping>
              <foreign-key-jdbc-name>cfk_ida</foreign-key-jdbc-name>
            </foreign-key-jdbc-mapping>
          </jonas-ejb-relationship-role>
        </jonas-ejb-relation>
        .....

Default values:

jonas-ejb-relation | Optional
foreign-key-jdbc-name | Optional. Default value is the abstract-schema-name of the destination bean of the "one" side of the relationship (i.e. the source bean of the relationship role with multiplicity one), suffixed by _, and by its primary-key-field. A_ida in the example.

##### 1-N bidirectional relationships

Similar to 1-N unidirectional relationships, but with a CMR field in each bean.

###### Standard Deployment Descriptor

        .....
        <relationships>
          <ejb-relation>
            <ejb-relation-name>a-b</ejb-relation-name>
            <ejb-relationship-role>
              <!-- A => B -->
                    <ejb-relationship-role-name>a2b</ejb-relationship-role-name>
              <multiplicity>One</multiplicity>
              <relationship-role-source>
                <ejb-name>A</ejb-name>
              </relationship-role-source>
              <cmr-field>
                <cmr-field-name>b</cmr-field-name>
                <cmr-field-type>java.util.Collection</cmr-field-type>
              </cmr-field>
            </ejb-relationship-role>
            <ejb-relationship-role>
              <!-- B => A -->
              <ejb-relationship-role-name>b2a</ejb-relationship-role-name>
              <multiplicity>Many</multiplicity>
              <relationship-role-source>
                <ejb-name>B</ejb-name>
              </relationship-role-source>
              <cmr-field>
                <cmr-field-name>a</cmr-field-name>
              </cmr-field>
            </ejb-relationship-role>
          </ejb-relation>
        </relationships>
        .....

###### Database mapping

t_A
c_idA
...

t_B |
c_idB | cfk_idA
... | ...

In this case, the foreign key must be in the table of the bean which is on the "many" side of the relationship (i.e. in the table of the source bean of the relationship role with multiplicity many), t_B.

###### JOnAS Deployment Descriptor

        .....
        <jonas-ejb-relation>
          <ejb-relation-name>a-b</ejb-relation-name>
          <jonas-ejb-relationship-role>
            <ejb-relationship-role-name>b2a</ejb-relationship-role-name>
            <foreign-key-jdbc-mapping>
              <foreign-key-jdbc-name>cfk_ida</foreign-key-jdbc-name>
            </foreign-key-jdbc-mapping>
          </jonas-ejb-relationship-role>
        </jonas-ejb-relation>
        .....

Default values:

jonas-ejb-relation | Optional
foreign-key-jdbc-name | Optional. Default value is the abstract-schema-name of the destination bean of the "one" side of the relationship (i.e. the source bean of the relationship role with multiplicity one), suffixed by _, and by its primary-key-field. A_ida in the example.

##### N-1 unidirectional relationships

Similar to 1-N unidirectional relationships, but the CMR field is defined on the "many" side of the relationship, i.e. on the (source bean of the) relationship role with multiplicity "many."

###### Standard Deployment Descriptor

        .....
        <relationships>
          <ejb-relation>
            <ejb-relation-name>a-b</ejb-relation-name>
            <ejb-relationship-role>
              <!-- A => B -->
                    <ejb-relationship-role-name>a2b</ejb-relationship-role-name>
              <multiplicity>Many</multiplicity>
              <relationship-role-source>
                <ejb-name>A</ejb-name>
              </relationship-role-source>
              <cmr-field>
                <cmr-field-name>b</cmr-field-name>
              </cmr-field>
            </ejb-relationship-role>
            <ejb-relationship-role>
              <!-- B => A -->
              <ejb-relationship-role-name>b2a</ejb-relationship-role-name>
              <multiplicity>One</multiplicity>
              <relationship-role-source>
                <ejb-name>B</ejb-name>
              </relationship-role-source>
            </ejb-relationship-role>
          </ejb-relation>
        </relationships>
        .....

###### Database mapping

t_A |
c_idA | cfk_idB
... | ...

t_B
c_idB
...

In this case, the foreign key must be in the table of the bean which is on the "many" side of the relationship (i.e. in table of the source bean of the relationship role with multiplicity many), t_A.

###### JOnAS Deployment Descriptor

        .....
        <jonas-ejb-relation>
          <ejb-relation-name>a-b</ejb-relation-name>
          <jonas-ejb-relationship-role>
            <ejb-relationship-role-name>a2b</ejb-relationship-role-name>
            <foreign-key-jdbc-mapping>
              <foreign-key-jdbc-name>cfk_idb</foreign-key-jdbc-name>
            </foreign-key-jdbc-mapping>
          </jonas-ejb-relationship-role>
        </jonas-ejb-relation>
        .....

Default values:

jonas-ejb-relation | Optional
foreign-key-jdbc-name | Optional. Default value is the abstract-schema-name of the destination bean of the "one" side of the relationship (i.e. the source bean of the relationship role with multiplicity one), suffixed by _, and by its primary-key-field. B_idb in the example.

##### N-M unidirectional relationships

###### Standard Deployment Descriptor

        .....
        <relationships>
          <ejb-relation>
            <ejb-relation-name>a-b</ejb-relation-name>
            <ejb-relationship-role>
              <!-- A => B -->
                    <ejb-relationship-role-name>a2b</ejb-relationship-role-name>
              <multiplicity>Many</multiplicity>
              <relationship-role-source>
                <ejb-name>A</ejb-name>
              </relationship-role-source>
              <cmr-field>
                <cmr-field-name>b</cmr-field-name>
                <cmr-field-type>java.util.Collection</cmr-field-type>
              </cmr-field>
            </ejb-relationship-role>
            <ejb-relationship-role>
              <!-- B => A -->
              <ejb-relationship-role-name>b2a</ejb-relationship-role-name>
              <multiplicity>Many</multiplicity>
              <relationship-role-source>
                <ejb-name>B</ejb-name>
              </relationship-role-source>
            </ejb-relationship-role>
          </ejb-relation>
        </relationships>
        .....

###### Database mapping

t_A
c_idA
...

t_B
c_idB
...

tJoin_AB |
cfk_idA | cfk_idB
... | ...

In this case, there is a join table composed of the foreign keys of each entity bean table.

###### JOnAS Deployment Descriptor

        .....
        <jonas-ejb-relation>
          <ejb-relation-name>a-b</ejb-relation-name>
          <jdbc-table-name>tJoin_AB</jdbc-table-name>
          <jonas-ejb-relationship-role>
            <ejb-relationship-role-name>a2b</ejb-relationship-role-name>
            <foreign-key-jdbc-mapping>
              <foreign-key-jdbc-name>cfk_idb</foreign-key-jdbc-name>
            </foreign-key-jdbc-mapping>
          </jonas-ejb-relationship-role>
          <jonas-ejb-relationship-role>
            <ejb-relationship-role-name>b2a</ejb-relationship-role-name>
            <foreign-key-jdbc-mapping>
              <foreign-key-jdbc-name>cfk_ida</foreign-key-jdbc-name>
            </foreign-key-jdbc-mapping>
          </jonas-ejb-relationship-role>
        </jonas-ejb-relation>
        .....

Default values

jonas-ejb-relation | Optional
jdbc-table-name | Optional. Default value is built from the abstract-schema-names of the beans, separated by _. A_B in the example.
foreign-key-jdbc-name | Optional. Default value is the abstract-schema-name of the destination bean, suffixed by _, and by its primary-key-field. B_idb and A_ida in the example.

##### N-M bidirectional relationships

Similar to N-M unidirectional relationships, but a CMR field is defined for each bean.

###### Standard deployment Descriptor

        .....
        <relationships>
          <ejb-relation>
            <ejb-relation-name>a-b</ejb-relation-name>
            <ejb-relationship-role>
              <!-- A => B -->
                    <ejb-relationship-role-name>a2b</ejb-relationship-role-name>
              <multiplicity>Many</multiplicity>
              <relationship-role-source>
                <ejb-name>A</ejb-name>
              </relationship-role-source>
              <cmr-field>
                <cmr-field-name>b</cmr-field-name>
                <cmr-field-type>java.util.Collection</cmr-field-type>
              </cmr-field>
            </ejb-relationship-role>
            <ejb-relationship-role>
              <!-- B => A -->
              <ejb-relationship-role-name>b2a</ejb-relationship-role-name>
              <multiplicity>Many</multiplicity>
              <relationship-role-source>
                <ejb-name>B</ejb-name>
              </relationship-role-source>
              <cmr-field>
                <cmr-field-name>a</cmr-field-name>
                <cmr-field-type>java.util.Collection</cmr-field-type>
              </cmr-field>
            </ejb-relationship-role>
          </ejb-relation>
        </relationships>
        .....

###### Database mapping

t_A
c_idA
...

t_B
c_idB
...

tJoin_AB |
cfk_idA | cfk_idB
... | ...

In this case, there is a join table composed of the foreign keys of each entity bean table.

###### JOnAS Deployment Descriptor

        .....
        <jonas-ejb-relation>
          <ejb-relation-name>a-b</ejb-relation-name>
          <jdbc-table-name>tJoin_AB</jdbc-table-name>
          <jonas-ejb-relationship-role>
            <ejb-relationship-role-name>a2b</ejb-relationship-role-name>
            <foreign-key-jdbc-mapping>
              <foreign-key-jdbc-name>cfk_idb</foreign-key-jdbc-name>
            </foreign-key-jdbc-mapping>
          </jonas-ejb-relationship-role>
          <jonas-ejb-relationship-role>
            <ejb-relationship-role-name>b2a</ejb-relationship-role-name>
            <foreign-key-jdbc-mapping>
              <foreign-key-jdbc-name>cfk_ida</foreign-key-jdbc-name>
            </foreign-key-jdbc-mapping>
          </jonas-ejb-relationship-role>
        </jonas-ejb-relation>
        .....

Default values:

jonas-ejb-relation | Optional
jdbc-table-name | Optional. Default value is built from the abstract-schema-names of the beans, separated by _. A_B in the example.
foreign-key-jdbc-name | Optional. Default value is the abstract-schema-name of the destination bean, suffixed by _, and by its primary-key-field. B_idb and A_ida in the example.

#### CMR fields Mapping to composite primary-keys

In the case of composite primary keys, the database mapping should provide the capability to specify which column of a foreign key corresponds to which column of the primary key. This is the only difference between relationships based on simple primary keys. For this reason, not all types of relationship are illustrated below.

##### 1-1 bidirectional relationships

###### Standard Deployment Descriptor

        .....
        <entity>
          <ejb-name>A</ejb-name>
          .....
          <prim-key-class>p.PkA</prim-key-class>
          .....
          <cmp-field>
            <field-name>id1A</field-name>
          </cmp-field>
          <cmp-field>
            <field-name>id2A</field-name>
          </cmp-field>
          .....
        </entity>
        .....
        <entity>
          <ejb-name>B</ejb-name>
          .....
          <prim-key-class>p.PkB</prim-key-class>
          .....
          <cmp-field>
            <field-name>id1B</field-name>
          </cmp-field>
          <cmp-field>
            <field-name>id2B</field-name>
          </cmp-field>
          .....
        </entity>
        .....
        <relationships>
          <ejb-relation>
            <ejb-relation-name>a-b</ejb-relation-name>
            <ejb-relationship-role>
              <!-- A => B -->
                    <ejb-relationship-role-name>a2b</ejb-relationship-role-name>
              <multiplicity>One</multiplicity>
              <relationship-role-source>
                <ejb-name>A</ejb-name>
              </relationship-role-source>
              <cmr-field>
                <cmr-field-name>b</cmr-field-name>
              </cmr-field>
            </ejb-relationship-role>
            <ejb-relationship-role>
              <!-- B => A -->
              <ejb-relationship-role-name>b2a</ejb-relationship-role-name>
              <multiplicity>One</multiplicity>
              <relationship-role-source>
                <ejb-name>B</ejb-name>
              </relationship-role-source>
              <cmr-field>
                <cmr-field-name>a</cmr-field-name>
              </cmr-field>
            </ejb-relationship-role>
          </ejb-relation>
        </relationships>
        .....

###### Database mapping

Two mappings are possible, one or another of the tables may hold the foreign key.

Case 1:

t_A |  |  |
c_id1A | c_id2A | cfk_id1B | cfk_id2B
... | ... | ... | ...

t_B |
c_id1B | c_id2B
... | ...

Case 2:

t_A |
c_id1A | c_id2A
... | ...

t_B |  |  |
c_id1B | c_id2B | cfk_id1A | cfk_id2A
... | ... | ... | ...

###### JOnAS Deployment Descriptor

Case 1:

        .....
        <jonas-ejb-relation>
          <ejb-relation-name>a-b</ejb-relation-name>
          <jonas-ejb-relationship-role>
            <ejb-relationship-role-name>a2b</ejb-relationship-role-name>
            <foreign-key-jdbc-mapping>
              <foreign-key-jdbc-name>cfk_id1b</foreign-key-jdbc-name>
              <key-jdbc-name>c_id1b</key-jdbc-name>
            </foreign-key-jdbc-mapping>
            <foreign-key-jdbc-mapping>
              <foreign-key-jdbc-name>cfk_id2b</foreign-key-jdbc-name>
              <key-jdbc-name>c_id2b</key-jdbc-name>
            </foreign-key-jdbc-mapping>
          </jonas-ejb-relationship-role>
        </jonas-ejb-relation>
        .....

Case 2:

        .....
        <jonas-ejb-relation>
          <ejb-relation-name>a-b</ejb-relation-name>
          <jonas-ejb-relationship-role>
            <ejb-relationship-role-name>b2a</ejb-relationship-role-name>
            <foreign-key-jdbc-mapping>
              <foreign-key-jdbc-name>cfk_id1a</foreign-key-jdbc-name>
              <key-jdbc-name>c_id1a</key-jdbc-name>
            </foreign-key-jdbc-mapping>
            <foreign-key-jdbc-mapping>
              <foreign-key-jdbc-name>cfk_id2a</foreign-key-jdbc-name>
              <key-jdbc-name>c_id2a</key-jdbc-name>
            </foreign-key-jdbc-mapping>
          </jonas-ejb-relationship-role>
        </jonas-ejb-relation>
        .....

For the default mapping (values), the foreign key is in the table of the source bean of the first ejb-relationship-role of the ejb-relation. In the example, the default mapping corresponds to case 1, since the ejb-relationship-role a2b is the first defined in the ejb-relation a-b.

##### N-M unidirectional relationships

###### Standard Deployment Descriptor

        .....
        <entity>
          <ejb-name>A</ejb-name>
          .....
          <cmp-field>
            <field-name>id1A</field-name>
          </cmp-field>
          <cmp-field>
            <field-name>id2A</field-name>
          </cmp-field>
          .....
        </entity>
        .....
        <entity>
          <ejb-name>B</ejb-name>
          .....
          <cmp-field>
            <field-name>id1B</field-name>
          </cmp-field>
          <cmp-field>
            <field-name>id2B</field-name>
          </cmp-field>
          .....
        </entity>
        .....
        <relationships>
          <ejb-relation>
            <ejb-relation-name>a-b</ejb-relation-name>
            <ejb-relationship-role>
              <!-- A => B -->
                    <ejb-relationship-role-name>a2b</ejb-relationship-role-name>
              <multiplicity>Many</multiplicity>
              <relationship-role-source>
                <ejb-name>A</ejb-name>
              </relationship-role-source>
              <cmr-field>
                <cmr-field-name>b</cmr-field-name>
                <cmr-field-type>java.util.Collection</cmr-field-type>
              </cmr-field>
            </ejb-relationship-role>
            <ejb-relationship-role>
              <!-- B => A -->
              <ejb-relationship-role-name>b2a</ejb-relationship-role-name>
              <multiplicity>Many</multiplicity>
              <relationship-role-source>
                <ejb-name>B</ejb-name>
              </relationship-role-source>
            </ejb-relationship-role>
          </ejb-relation>
        </relationships>
        .....

###### Database mapping

t_A |
c_id1A | c_id2A
... | ...

t_B |
c_id1B | c_id2B
... | ...

tJoin_AB |  |  |
cfk_id1A | cfk_id2A | cfk_id1B | cfk_id2B
... | ... | ... | ...

In this case, there is a join table composed of the foreign keys of each entity bean table.

###### JOnAS Deployment Descriptor

        .....
        <jonas-ejb-relation>
          <ejb-relation-name>a-b</ejb-relation-name>
          <jdbc-table-name>tJoin_AB</jdbc-table-name>
          <jonas-ejb-relationship-role>
            <ejb-relationship-role-name>a2b</ejb-relationship-role-name>
            <foreign-key-jdbc-mapping>
              <foreign-key-jdbc-name>cfk_id1b</foreign-key-jdbc-name>
              <key-jdbc-name>c_id1b</key-jdbc-name>
            </foreign-key-jdbc-mapping>
            <foreign-key-jdbc-mapping>
              <foreign-key-jdbc-name>cfk_id2b</foreign-key-jdbc-name>
              <key-jdbc-name>c_id2b</key-jdbc-name>
            </foreign-key-jdbc-mapping>
          </jonas-ejb-relationship-role>
          <jonas-ejb-relationship-role>
            <ejb-relationship-role-name>b2a</ejb-relationship-role-name>
            <foreign-key-jdbc-mapping>
              <foreign-key-jdbc-name>cfk_id1a</foreign-key-jdbc-name>
              <key-jdbc-name>c_id1a</key-jdbc-name>
            </foreign-key-jdbc-mapping>
            <foreign-key-jdbc-mapping>
              <foreign-key-jdbc-name>cfk_id2a</foreign-key-jdbc-name>
              <key-jdbc-name>c_id2a</key-jdbc-name>
            </foreign-key-jdbc-mapping>
          </jonas-ejb-relationship-role>
        </jonas-ejb-relation>
        .....