8.7. 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:

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>
  </cmp-field-jdbc-mapping>
</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:

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

For an explicit mapping definition, refer to Section 8.11 JOnAS Database Mapping (Specific Deployment Descriptor).

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 behavior of the implementation of a find<method> method (that is, 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 > 
     ?</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 > 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 behavior of the implementation of a find<method> method is located in the standard deployment descriptor, as an EJB-QL query (that is, 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 
    > ?1</ejb-ql>
</query>