Sun logo      Previous      Contents      Index      Next     

J2EE 1.4 Application Server Developer's Guide

Chapter 3
Using Container-Managed Persistence for Entity Beans

This section contains information on how container-managed persistence works in the J2EE 1.4 Application Server environment. This section addresses the following topics:

Extensive information on container-managed persistence is contained in chapters 10, 11, and 14 of the Enterprise JavaBeans Specification, v2.1.


J2EE 1.4 Application Server Support

J2EE 1.4 Application Server support for container-managed persistence includes:


Deployment Descriptors

If your container-managed fields are to be mapped to database fields, you must provide mapping information to the deployer. Each module with container-managed persistence beans must have the following files:


Using Container-Managed Persistence

Implementation for entity beans that use container-managed persistence is mostly a matter of mapping, assembly, and deployment.


Note

Java types assigned to CMP fields must be restricted to Java primitive types or Java Serializable types. An entity bean local interface type (or a collection of such) can be the type of a CMR field.


This section addresses the following topics:

Process Overview

The container-managed persistence process consists of three operations: mapping, deploying, and running. These operations are accomplished as described in the following phases:

Phase 1. Creating the mapping deployment descriptor file

The J2EE 1.4 Application Server creates the mappings in the descriptor file sun-cmp-mappings.xml automatically during deployment if the file is not present.

The sun-cmp-mappings.xml file maps CMP fields and CMR fields (relationships) to the database. A primary table must be selected for each container-managed persistence bean, and optionally, multiple secondary tables. CMP fields are mapped to columns in either the primary or secondary table(s). CMR fields are mapped to pairs of column lists (normally, column lists are the list of columns associated with pairs of primary and foreign keys).

For details about mapping, see "Mapping Fields and Relationships Manually".

Phase 2. Deploying concrete beans and delegates

This phase consists of deploying an EJB application to the J2EE 1.4 Application Server. During this phase, deployment information is combined with the mapping information created during Phase 1.

The following files are generated:

Phase 3. Running in the J2EE 1.4 Application Server runtime

At runtime, the information provided at deployment is used to service requests on entities implemented as enterprise beans.

Mapping Capabilities

Mapping refers to the ability to tie an object-oriented model to a relational model of data, usually the schema of a relational database. The container-managed persistence implementation provides the ability to tie a set of interrelated beans containing data and associated behaviors to the interrelated meta-data of the schema. You can then use this object representation of the database to form the basis of a Java application. You can also customize this mapping to optimize these underlying beans for the particular needs of an application.

The result is a single data model through which you can access both persistent database information and regular transient program data. You only need to understand the Java programming language objects; you do not need to know or understand the underlying database schema.

Information on the container-managed persistence DTD and XML file elements is contained in "Elements in the sun-cmp-mappings.xml File".

The mapping capabilities provided by the J2EE 1.4 Application Server include:

Automatic Mapping Options

You can control automatic mapping in the following ways using deployment descriptor elements or command line options. You can:

The following optional data subelements of the cmp-resource element in the sun-ejb-jar.xml file control the automatic creation of database tables at deployment:

Table 3-1  sun-ejb-jar.xml Mapping Elements

Element

Default

Description

create-tables-at-deploy

false

If true, causes database tables to be created for beans that are automaticaly mapped by the EJB container. If false, does not create tables.

drop-tables-at-undeploy

false

If true, causes existing database tables for beans being undeployed to be dropped in the database.

database-vendor-name

none

Specifies the name of the database vendor for which tables can be created. Allowed values are db2, mssql, oracle, pointbase, and sybase, case-insensitive.

If no value is specified, a connection is made to the resource and the database vendor name is read. If connection fails, or if the value is not recognized, SQL-92 compliance is presumed.

schema-generator-properties

none

Allows you to specify mappings in property subelements.

Also allows you to set the use-unique-table-names property. If true, this property specifies that table names are unique within each application server domain. The default is false.

For example:

<schema-generator-properties>
  <property>
    <name>
      Employee.firstName.jdbc-type
    </name>
    <value>char</value>
  </property>
  <property>
    <name>
       Employee.firstName.jdbc-maximum-length
    </name>
    <value>25</value>
  </property>
  <property>
    <name>
      use-unique-table-names
    </name>
    <value>true</value>
  </property>
</schema-generator-properties>

The following options of the asadmin deploy or asadmin deploydir command control the automatic creation of database tables at deployment:

Table 3-2  asadmin deploy and asadmin deploydir Mapping Options

Option

Default

Description

--createtables

none

If true, causes database tables to be created for beans that need them. If false, does not create tables. If not specified, the value of the create-tables-at-deploy attribute in sun-ejb-jar.xml is used.

--dropandcreatetables

none

If true, and if tables were automatically created when this application was previously deployed, tables from the earlier deployment are dropped and fresh ones are created.

If true, and if tables were not automatically created when this application was previously deployed, no attempt is made to drop any tables. However, if tables with the same names as those that would have been automatically created are found, the deployment fails.

If false, settings of create-tables-at-deploy or drop-tables-at-undeploy in the sun-ejb-jar.xml file are overridden.

--uniquetablenames

none

If true, specifies that table names are unique within each application server domain. If not specified, the value of the use-unique-table-names property in sun-ejb-jar.xml is used.

--dbvendorname

none

Specifies the name of the database vendor for which tables can be created. Allowed values are db2, mssql, oracle, pointbase, and sybase, case-insensitive.

If not specified, the value of the database-vendor-name attribute in sun-ejb-jar.xml is used.

If no value is specified in sun-ejb-jar.xml, a connection is made to the resource and the database vendor name is read. If connection fails, or if the value is not recognized, SQL-92 compliance is presumed.

If you have manually mapped one or more of the beans in the module and you use any of the asadmin deploy or asadmin deploydir options, the deployment is not harmed in any way, but the options have no effect, and you get a warning in the server log.

If you used the deploytool to map one or more of the beans, the --uniquetablenames option has no effect when you run asadmin deploy or asadmin deploydir. The uniqueness of the table names was established when deploytool created the mapping.

The following options of the asadmin undeploy command control the automatic removal of database tables at undeployment:

Table 3-3  asadmin undeploy Mapping Options

Option

Default

Description

--droptables

none

If true, and if tables were automatically created when this application was previously deployed, causes database tables to be dropped for the bean(s) being undeployed. If false, does not drop tables.

If not specified, the value of the drop-tables-at-undeploy attribute in sun-ejb-jar.xml is used.

For more information about the asadmin deploy, asadmin deploydir, and asadmin undeploy commands, see the Administrator’s Guide.

When command line and sun-ejb-jar.xml options are both specified, the asadmin options take precedence.

Supported Data Types for Mapping

Container-managed persistence supports a set of JDBC data types that are used in mapping Java data fields to SQL types. Supported JDBC data types are as follows:

BIGINT          BIT        BLOB        CHAR        CLOB

DATE          DECIMAL        DOUBLE        FLOAT        INTEGER

LONGVARBINARY          LONGVARCHAR        NUMERIC        REAL        SMALLINT

TIME          TIMESTAMP        TINYINT        VARCHAR

The following table contains suggested Java type to JDBC type mappings.

Table 3-4  Suggested Java Type to JDBC Type Mappings 

Java Type

JDBC Type

Nullability

boolean

BIT

NON NULL

java.lang.Boolean

BOOLEAN

NULL

byte

TINYINT

NON NULL

java.lang.Byte

TINYINT

NULL

double

DOUBLE

NON NULL

java.lang.Double

DOUBLE

NULL

float

REAL

NON NULL

java.lang.Float

REAL

NULL

int

INTEGER

NON NULL

java.lang.Integer

INTEGER

NULL

long

BIGINT

NON NULL

java.lang.Long

BIGINT

NULL

short

SMALLINT

NON NULL

java.lang.Short

SMALLINT

NULL

java.math.BigDecimal

NUMERIC

NULL

java.lang.String

CHAR

NULL

java.lang.String

VARCHAR

NON NULL

java.lang.String

CLOB

NULL

Serializable

BLOB

NULL

byte[]

BLOB

NON NULL

java.util.Date

TIMESTAMP

NULL

java.sql.Time

TIME

NULL

java.sql.Date

DATE

NULL

java.sql.Timestamp

TIMESTAMP

NULL

The following table contains suggested mappings of JDBC types to database vendor specific types.

Table 3-5  Suggested Mappings of JDBC Types to Database Vendor Specific Types 

JDBC Type

PointBase

Oracle

BIT

BOOLEAN

SMALLINT

BOOLEAN

BOOLEAN

SMALLINT

TINYINT

SMALLINT

SMALLINT

SMALLINT

SMALLINT

SMALLINT

INTEGER

INTEGER

INTEGER

BIGINT

BIGINT

NUMBER

REAL

REAL

REAL

FLOAT

FLOAT

FLOAT

DOUBLE

DOUBLE PRECISION

DOUBLE PRECISION

NUMERIC(p,s)

NUMERIC(p,s)

NUMBER(p,s)

DECIMAL(p,s)

NUMERIC(p,s)

NUMBER(p,s)

VARCHAR

VARCHAR

VARCHAR2

DATE

DATE

DATE

TIME

TIME

DATE

TIMESTAMP

TIMESTAMP

TIMESTAMP

BLOB

BLOB

BLOB

CLOB

CLOB

CLOB

BLOB Support

Binary Large Object (BLOB) is a data type used to store and retrieve complex object fields. BLOBs are binary or Serializable objects, such as pictures, that translate into large byte arrays which are then serialized into CMP fields.

If a CMP field is defined as Serializable, it is serialized into a byte[] before being stored in the database. Similarly, the value fetched from the database is deserialized. However, if a CMP field is defined as byte[], it is not serialized and desrialized when stored and fetched, respectively.

To enable BLOB support in the J2EE 1.4 Application Server environment, define a CMP field of type byte[] or a user-defined type that implements the java.io.Serializable interface. If you map the CMP bean to an existing database schema, map the field to a column of type BLOB.

If you use automatic mapping, you might need to change the default BLOB column length for the generated schema using the schema-generator-properties element in sun-ejb-jar.xml. For example:

<schema-generator-properties>
  <property>
    <name>Employee.voiceGreeting.jdbc-type</name>
    <value>BLOB</value>
  </property>
  <property>
    <name>Employee.voiceGreeting.jdbc-maximum-length</name>
    <value>10240</value>
  </property>
  ...
</schema-generator-properties>

CLOB Support

Character Large Object (CLOB) is a data type used to store and retrieve very long text fields. CLOBs translate into long strings.

To enable CLOB support in the J2EE 1.4 Application Server environment, define a CMP field of type java.lang.String. If you map the CMP bean to an existing database schema, map the field to a column of type CLOB.

If you use automatic mapping, you might need to change the default CLOB column length for the generated schema using the schema-generator-properties element in sun-ejb-jar.xml. For example:

<schema-generator-properties>
  <property>
    <name>Employee.resume.jdbc-type</name>
    <value>CLOB</value>
  </property>
  <property>
    <name>Employee.resume.jdbc-maximum-length</name>
    <value>10240</value>
  </property>
  ...
</schema-generator-properties>

Capturing the Database Schema Automatically

You can configure a CMP bean in J2EE 1.4 Application Server to automatically capture the database metadata and save it in a .dbschema file during deployment. If the sun-cmp-mappings.xml file contains an empty schema entry, the cmp-resource entry in the sun-ejb-jar.xml file is used to get a connection to the database, and automatic generation of the schema is performed.

Using the capture-schema Utility

You can use the capture-schema command to manually generate the database metadata (.dbschema) file.


Note

An Oracle database user running the capture-schema command needs ANALYZE ANY TABLE privileges if that user does not own the schema. These privileges are granted to the user by the database administrator.

The capture-schema utility does not modify the schema in any way. Its only purpose is to provide the persistence engine with information about the structure of the database (the schema).


Syntax

capture-schema -dburl url -username username -password password -driver jdbcdriver [-schemaname schemaname] [-table tablename]* [-out filename]

Where:

-dburl url: Specifies the JDBC URL expected by the driver for accessing a database.

-username username: Specifies the user name for authenticating access to a database.

-password password: Specifies the password for accessing the selected database.

-driver jdbcdriver: Specifies the JDBC driver class name. This class must be in your CLASSPATH.

-schemaname schemaname: Specifies the name of the user schema being captured. If not specified, the default will capture metadata for all tables from all the schemas accessible to this user.


Note

If more than one schema is accessible for this user, more than one table with the same name might be captured, which will cause problems if this parameter is not set.


-table tablename: Specifies a table name. Multiple table names can be specified. If not specified, all the tables in the database schema will be captured.

-out: Specifies the output target. Defaults to stdout. To be able to use the output for the CMP mapping, the output file name must have the .dbschema suffix.

For container-managed persistence mapping, the -out parameter correlates to the schema subelement of the sun-cmp-mapping element in the sun-cmp-mappings.xml file. In this file, this file name must be specified without the .dbschema suffix. For example:

<schema>RosterSchema</schema>


Note

If no -table option is given, all the tables in the database are captured in the schema.


Example

capture-schema -dburl jdbc:pointbase:server://localhost:9092/sample -username public -password public -driver com.pointbase.jdbc.jdbcUniversalDriver -out RosterSchema.dbschema

Mapping Fields and Relationships Manually

This section discusses how to map the fields and relationships of your entity beans manually, by editing the sun-cmp-mappings.xml deployment descriptor. You should only do this if you are proficient in editing XML. For other mapping alternatives, see "Automatic Mapping Options".

A container-managed persistence bean has a name, a primary table, zero or more secondary tables, one or more fields, zero or more relationships, and zero or more secondary tables, plus flags for consistency checking. You will need to map the CMP fields and CMR fields to the database using the elements in the sun-cmp-mappings.xml file. CMP fields are mapped to columns in either the primary or secondary database table(s); CMR fields are mapped to pairs of column lists.

An alphabetic listing of the mapping elements in the container-managed persistence deployment descriptors is contained in "Elements in the sun-cmp-mappings.xml File". A sample XML file is contained in "Sample Schema Definition".

This section contains instructions for accomplishing the following mapping tasks:

Specifying the Beans to Be Mapped

You must start by using the following elements to specify the database schema and the container-managed persistence beans being mapped:

sun-cmp-mappings

Specifies the collection of subelements for all the beans that will be mapped in an EJB JAR collection.

Subelement is sun-cmp-mapping.

Example

Refer to "Sample Schema Definition".

sun-cmp-mapping

Specifies beans mapped to a particular schema.

Subelements are schema, entity-mapping.

schema

Specifies the path to the schema file if the file was manually generated. The path is relative to the directory containing the sun-cmp-mappings.xml file, and the file name omits the .dbschema extension. To use automatic schema generation, do not specify a value for this element.

Example

<schema>RosterSchema</schema> <!-- named schema>

<schema></schema> <!-- use automatic schema generation>

Specifying the Mapping Components

The next step is to use the following elements to specify components that are part of the mapping, and to indicate how consistency checking will occur.

entity-mapping

Specifies the mapping of beans to database columns.

Subelements are ejb-name, table-name, cmp-field-mapping, cmr-field-mapping, secondary-table, consistency.

Example

<entity-mapping>
  <ejb-name>Player</ejb-name>
  <table-name>Player</table-name>
  <cmp-field-mapping>
    <field-name>salary</field-name>
    <column-name>Player.salary</column-name>
  </cmp-field-mapping>
  <cmp-field-mapping>
    <field-name>playerId</field-name>
    <column-name>Player.player_Id</column-name>
  </cmp-field-mapping>
  <cmp-field-mapping>
    <field-name>position</field-name>
    <column-name>Player.position</column-name>
  </cmp-field-mapping>
    <field-name>name</field-name>
    <column-name>Player.name</column-name>
  </cmp-field-mapping>
  <cmr-field-mapping>
    <cmr-field-name>teamId</cmr-field-name>
    <column-pair>
      <column-name>Player.player_Id</column-name>
      <column-name>TEAMPLAYER.player_Id</column-name>
    </column-pair>
    <column-pair>
      <column-name>TEAMPLAYER.team_Id</column-name>
      <column-name>Team.team_Id</column-name>
    </column-pair>
  </cmr-field-mapping>
</entity-mapping>

ejb-name

Specifies the name of the entity bean in the ejb-jar.xml file to which the container-managed persistence beans relates. One is required.

Example

<ejb-name>Player</ejb-name>

table-name

Specifies the name of a database table. The table must be present in the database schema file. One is required.

Example

<table-name>PLAYER</table-name>

secondary-table

Specifies a bean’s secondary table(s). Optional.

Subelements are table-name, column-pair.

Example

In this secondary table example, an email field is added to a StudentEJB class, which may look like this:

public abstract class StudentEJB implements EntityBean {

  /***************************************************
  Write your set,get methods for Entity bean variables and
  business methods here
  ***************************************************/
  //Access methods for CMP fields
  public abstract Integer getStudentId();
  public abstract void setStudentId(Integer studentId);
  public abstract String getStudentName();
  public abstract void setStudentName(String studentName);

  //Column from secondary table
  public abstract String getEmail();
  public abstract void setEmail(String Email); <-----
  ...
}

The Student and the Email table should be related by a foreign key. The schemas for the tables may look like this:

CREATE TABLE STUDENT (
  STUDENT_ID NUMBER PRIMARY KEY,
  STUDENT_NAME VARCHAR
);

CREATE TABLE EMAIL (
  STUDENT_ID NUMBER PRIMARY KEY,
  EMAIL_ADDRESS VARCHAR
);

The sun-cmp-mappings file may look like this:

<sun-cmp-mappings>
  <sun-cmp-mapping>
    ...
    <entity-mapping>
      <ejb-name>StudentEJB</ejb-name>
      <table-name>STUDENT</table-name>
      <cmp-field-mapping>
        <field-name>studentId</field-name>
        <column-name>STUDENT.STUDENT_ID</column-name>
      </cmp-field-mapping>
      <cmp-field-mapping>
        <field-name>email</field-name>
        <column-name>EMAIL.EMAIL_ADDRESS</column-name>
      </cmp-field-mapping>
      ...
    <secondary-table>
      <table-name>EMAIL</table-name>
      <column-pair>
        <column-name>STUDENT.STUDENT_ID</column-name>
        <column-name>EMAIL.STUDENT_ID</column-name>
      </column-pair>
    </secondary-table>
  </entity-mapping>
  ...
  <sun-cmp-mapping>
<sun-cmp-mappings>

When you add the secondary table, the tables are both used by the same enterprise bean.

consistency

Specifies container behavior in guaranteeing transactional consistency of the data in the bean. Optional. If the consistency checking flag element is not present, none is assumed.

The following table describes the elements used for consistency checking.

Table 3-6  Consistency Flags 

Flag Element

Description

check-all-at-commit

This flag is not implemented for J2EE 1.4 Application Server.

check-modified-at-commit

Checks modified instances at commit time.

lock-when-loaded

A lock is placed when the data is loaded.

lock-when-modified

This flag is not implemented for J2EE 1.4 Application Server.

none

No consistency checking occurs.

Specifying Field Mappings

Field mapping is done using the following elements:

cmp-field-mapping

The cmp-field-mapping element associates a field with one or more columns that it maps to. The column can be from a bean’s primary table or any defined secondary table. If a field is mapped to multiple columns, the column listed first in this element is used as a source for getting the value from the database. The columns are updated in the order they appear. There is one cmp-field-mapping element for each cmp-field element defined in the EJB JAR file.

Subelements are field-name, column-name, read-only, and fetched-with.

Example

<cmp-field-mapping>
  <field-name>name</field-name>
  <column-name>LEAGUE.NAME</column-name>
</cmp-field-mapping>

field-name

Specifies the Java identifier of a field. This identifier must match the value of the field-name subelement of the cmp-field that is being mapped. One is required.

Example

<field-name>name</field-name>

column-name

Specifies the name of a column from the primary table, or the table qualified name (TABLE.COLUMN) of a column from a secondary or related table. One or more is required.

Example

<column-name>PLAYER.NAME</column-name>

Example

Use this with non-normalized tables where the same information appears in multiple places, and the information needs to be kept synchronized if it is updated.

public abstract class StudentEJB implements EntityBean {
.
.
.

public abstract String getInstallments();

The three columns from the student table can be mapped to a single installments field in the Student enterprise bean.

<cmp-field-mapping>
  <field-name>installment</field-name>
  <column-name>Student.installment1</column-name>
  <column-name>Student.installment2</column-name>
  <column-name>Student.installment3</column-name>
</cmp-field-mapping>

The same value will be written to all the columns in the database.

read-only

The read-only flag indicates that a field is read-only.

Example

<read-only></read-only>

fetched-with

Specifies the fetch group configuration for fields and relationships. A field may participate in a hierarchical or independent fetch group. Optional.

The fetched-with element has different default values based on its parent element.

Subelements are level, named-group, or none.

level

Specifies the name of a hierarchical fetch group. The name must be an integer. Fields and relationships that belong to a hierarchical fetch group of equal (or lesser) value are fetched at the same time. The value of level must be greater than zero. Only one is allowed.

named-group

Specifies the name of an independent fetch group. All the fields and relationships that are part of a named group are fetched at the same time. Only one is allowed.

none

As a subelement of fetched-with, this flag indicates that this field or relationship is fetched by itself.

Specifying Relationships

The following elements are used to specify the mapping for container-managed relationships:

cmr-field-mapping

A container-managed relationship field has a name and one or more column pairs that define the relationship. There is one cmr-field-mapping element for each cmr-field. A relationship can also participate in a fetch group.

Subelements are cmr-field-name, column-pair, fetched-with.

Example

<cmr-field-mapping>
  <cmr-field-name>teams</cmr-field-name>
  <column-pair>
    <column-name>LEAGUE.LEAGUE_ID</column-name>
    <column-name>TEAM.LEAGUE_ID</column-name>
  </column-pair>
</cmr-field-mapping>

cmr-field-name

Specifies the Java identifier of a field. This must match the value of the cmr-field-name subelement of the cmr-field that is being mapped. One is required.

Example

<cmr-field-name>teams</cmr-field-name>

column-pair

Specifies a pair of columns in two database tables that relate the tables to each other. Each column-pair must contain exactly two column-name subelements, which specify the column’s names. The first column-name element names the table that this bean is mapped to, and the second column-name names the column in the related table.

Example

<column-pair>
  <column-name>LEAGUE.LEAGUE_ID</column-name>
  <column-name>TEAM.LEAGUE_ID</column-name>
</column-pair>

column-name

Specifies the name of a column from the primary table, or the table qualified name (TABLE.COLUMN) of a column from a secondary or related table. Two are required as subelements of a column-pair.

Example

<column-name>TEAM.LEAGUE_ID</column-name>

fetched-with

Specifies the fetch group configuration for fields and relationships. A field may participate in a hierarchical or independent fetch group. Optional.

The fetched-with element has different default values based on its parent element.

Subelements are level, named-group, or none.

Configuring the Resource Manager

The resource manager used by the container-managed persistence implementation is PersistenceManagerFactory, which is configured using the J2EE 1.4 Application Server XML file, domain.xml. Refer to the J2EE 1.4 Application Server Administrator’s Guide for information on creating a new persistence manager.

To deploy an EJB module that contains container-managed persistence beans, you need to specify the JNDI name of the Persistence Manager’s resource (which is a persistence-manager-factory-resource or jdbc-resource entry in the domain.xml file) in the jndi-name attribute of the cmp-resource. This name is used at run time to manage persistent resources.

If the JNDI name refers to a jdbc-resource entry, you can also set PersistenceManagerFactory properties as properties of the cmp-resource element in the sun-ejb-jar.xml file.

For example, if you have the following entry in the domain.xml file:

<persistence-manager-factory-resource
  factory-class="com.sun.jdo.spi.persistence.support.
    sqlstore.impl.PersistenceManagerFactoryImpl"
  enabled="true"
  jndi-name="jdo/pmf"
  jdbc-resource-jndi-name="jdo/pmfPM">

Set the CMP resource in the sun-ejb-jar.xml file as follows:

<cmp-resource>
  <jndi-name>jdo/pmf</jndi-name>
</cmp-resource>

Configuring Queries for 1.1 Finders

The Enterprise JavaBeans Specification, v1.1 spec does not specify the format of the finder method description. The J2EE 1.4 Application Server uses an extension of Java Data Objects Query Language (JDOQL) queries to implement finder and selector methods. For EJB 2.1, the container automatically maps an EJB QL query to JDOQL. For EJB 1.1, this mapping is partially done by the developer. You can specify the following elements of the underlying JDOQL query:

The J2EE 1.4 Application Server-specific deployment descriptor (sun-ejb-jar.xml) provides the following elements to store the EJB 1.1 finder method settings:

The J2EE 1.4 Application Server constructs a JDOQL query using the persistence capable class of the EJB 1.1 entity bean as the candidate class. It adds the filter, parameter declarations, and variable declaration and ordering as specified by the developer to the JDOQL query. It executes the query and passes the parameters of the finder method to the execute call. The objects from the JDOQL query result set are converted into primary key instances to be returned by the EJB 1.1 ejbFind method.

The JDO specification (see JSR 12) provides a comprehensive description of JDOQL. The following information summarizes the elements used to define EJB 1.1 finders.

Query Filter Expression

The filter expression is a String containing a boolean expression evaluated for each instance of the candidate class. If the filter is not specified, it defaults to true. Rules for constructing valid expressions follow the Java language, with the following differences:

The following expressions are supported:

Query Parameter

The parameter declaration is a String containing one or more parameter type declarations separated by commas. This follows the Java syntax for method signatures.

Query Variables

The type declarations follow the Java syntax for local variable declarations.

Example1

The following query returns all players called Michael. It defines a filter that compares the name field with a string literal:

The finder element of the sun-ejb-jar.xml file would look like this:

<finder>
  <method-name>findPlayerByName</method-name>
  <query-filter>name == "Michael"</query-filter>
</finder>

Example 2

This query returns all products in a specified price range. It defines two query parameters which are the lower and upper bound for the price: double low, double high. The filter compares the query parameters with the price field:

The finder element of the sun-ejb-jar.xml file would look like this:

<finder>
  <method-name>findInRange</method-name>
  <query-params>double low, double high</query-params>
  <query-filter>low &lt; price &amp;&amp; price &lt high</query-filter>
</finder>

Example 3

This query returns all players having a higher salary than the player with the specified name. It defines a query parameter for the name java.lang.String name. Furthermore, it defines a variable for the player to compare with. It has the type of the persistence capable class that corresponds to the bean:

  mypackage.PlayerEJB_170160966_JDOState p

The filter compares the salary of the current player denoted by this keyword with the salary of the player with the specified name:

  (this.salary > p.salary) && (p.name == name)

The finder element of the sun-ejb-jar.xml file would look like:

<finder>
  <method-name>findByHigherSalary</method-name>
  <query-params>java.lang.String name</query-params>
  <query-filter>
    (this.salary &gt; p.salary) &amp;&amp;
    (p.name ==name)
  </query-filter>
  <query-variables>mypackage.PlayerEJB_170160966_JDOState p</query-variables>
</finder>


Third-Party Pluggable Persistence Manager API

Container-managed persistence in the EJB container can support persistence vendors integrating their runtimes into the J2EE 1.4 Application Server using the J2EE 1.4 Application Server Pluggable Persistence Manager API. The API describes integration requirements at deployment, at code-generation, and at runtime. It supports callouts to implement the concrete bean implementations when beans are compiled.

The J2EE 1.4 Application Server enables the container-managed persistence implementation to use its startup framework to load classes and to register the persistence manager. The Pluggable Persistence Manager API also supports integration requirements with regard to transactions and dynamic deployment.

In general, the objective is that any third-party container-managed persistence solution that fully supports the Enterprise JavaBeans Specification, v2.1 can be made to work with the J2EE 1.4 Application Server.

To use a third-party tool:

  1. Build your enterprise beans using the third-party O/R mapping tool.
  2. Deploy the beans using the Administration Console or the command-line interface.

Third-party persistence tools must use Java Database Connectivity (JDBC) resources or Java Connector API (JCA) resources at runtime to access relational data sources. This allows the pluggable persistence managers to automatically use the Connection Pooling, transaction handling, and security management features of the container. Third-party vendors will be able to plug in their concrete class generators and their mapping factory to generate a valid vendor-specific mapping object model.

The configuration requirements specify a number of properties which must be defined for a bean, including:


Restrictions and Optimizations

This section discusses any restrictions and performance optimizations you should be aware of in implementing container-managed persistence for entity beans.

Unique Database Schema Names in EAR File

In a situation where there are multiple JAR files within an EAR file, for example jar1 and jar2, any corresponding .dbschema files for jar1 and jar2 must have unique fully qualified names.

Eager Loading of Field State

By default, the EJB container loads the state for all CMP fields (except BLOB and CLOB fields) before invoking the ejbLoad method of the abstract bean. This approach may not be optimal for entity objects with large state if most business methods require access to only parts of the state. If this is an issue, use the <fetched-with> element for fields that are used infrequently.

Restrictions on Remote Interfaces

The following restrictions apply to the remote interface of an entity bean that uses container-managed persistence:

Dependent value classes can be exposed in the remote interface or remote home interface, and can be included in the client EJB JAR file.

Sybase Finder Limitation

If you execute any finder method with an input greater than 255 characters and map the primary key column to a VARCHAR column, Sybase attempts to convert type VARCHAR to type TEXT and generates the following error:

com.sybase.jdbc2.jdbc.SybSQLException: Implicit conversion from datatype 'TEXT' to 'VARCHAR' is not allowed. Use the CONVERT function to run this query.

To avoid this error, make sure your finder method input is less than 255 characters.

Date and Time Fields as CMP Field Types

If a CMP field type is a Java date or time type (java.util.Date, java.sql.Date, java.sql.Time, java.sql.Timestamp), make sure that the field value exactly matches the value in the database.

For example, the following code uses a java.sql.Date type as a primary key field:

java.sql.Date myDate = new java.sql.Date(System.currentTimeMillis())
beanHome.create(myDate, ...);

This code results in only the year, month, and date portion of the field value being stored in the database. Later on if the client tries to find this bean by primary key as follows:

myBean = beanHome.findByPrimaryKey(myDate);

the bean is not found in the database because the value does not match the one that is stored in the database.

Similar problems can happen if the database truncates the timestamp value while storing it, or if a custom query has a date or time value comparison in its WHERE clause.


Elements in the sun-cmp-mappings.xml File

A sample XML file is contained in "Sample Schema Definition".

This section describes the elements in the sun-cmp-mappings.xml file:

check-all-at-commit

This flag is not implemented for J2EE 1.4 Application Server.

Subelements

none

check-modified-at-commit

A consistency level flag that indicates to check modified bean instances at commit time.

Subelements

none

cmp-field-mapping

The cmp-field-mapping element associates a field with one or more columns that it maps to. The column can be from a bean’s primary table or any defined secondary table. If a field is mapped to multiple columns, the column listed first in this element is used as a source for getting the value from the database. The columns are updated in the order they appear. There is one cmp-field-mapping element for each cmp-field element defined in the EJB JAR file.

A field may participate in a fetch group if the fetched-with element is not specified. The following is assumed:

<fetched-with><level>0</level></fetched-with>

Subelements

The following table describes subelements for the cmp-field-mapping element.

Table 3-7  cmp-field-mapping Subelements 

Subelement

Required

Description

field-name

only one

Specifies the Java identifier of a field. This identifier must match the value of the field-name subelement of the cmp-field that is being mapped. One is required.

column-name

one or more

Specifies the name of a column from the primary table, or the table qualified name (TABLE.COLUMN) of a column from a secondary or related table. One is required.

read-only

zero or one

Flag that indicates a field is read-only. Optional.

fetched-with

zero or one

Specifies the fetch group configuration for fields and relationships. Optional.

cmr-field-mapping

A container-managed relationship field has a name and one or more column pairs that define the relationship. There is one cmr-field-mapping element for each cmr-field. A relationship can also participate in a fetch group.

If the fetched-with element is not present, the following value is assumed: <fetched-with><none/></fetched-with>.

Subelements

The following table describes subelements for the cmr-field-mapping element.

Table 3-8  cmr-field-mapping Subelements 

Subelement

Required

Description

cmr-field-name

only one

Specifies the Java identifier of a field. Must match the value of the cmr-field-name subelement of the cmr-field that is being mapped.

column-pair

one or more

The name of the pair of columns in a database table.

fetched-with

zero or one

Specifies the fetch group configuration for fields and relationships. Optional.

cmr-field-name

Specifies the Java identifier of a field. Must match the value of the cmr-field-name subelement of the cmr-field that is being mapped.

Subelements

none

column-name

Specifies the name of a column from the primary table, or the table qualified name (TABLE.COLUMN) of a column from a secondary or related table. One is required.

Subelements

none

column-pair

Specifies a pair of columns in two database tables that relate the tables to each other. Each column-pair must contain exactly two column-name subelements, which specify the column’s names. The first column-name element names the table that this bean is mapped to, and the second column-name names the column in the related table.

Subelements

The following table describes subelements for the column-pair element.

Table 3-9  column-pair Subelements 

Subelement

Required

Description

column-name

two

Specifies the name of a column from the primary table, or the table qualified name (TABLE.COLUMN) of a column from a secondary or related table.

consistency

Specifies container behavior in guaranteeing transactional consistency of the data in the bean. Optional. If the consistency checking flag element is not present, none is assumed.

Subelements

The following table describes the elements used for consistency checking.

Table 3-10  Consistency Flags 

Flag Element

Description

check-all-at-commit

Checks modified instances at commit time.

check-modified-at-commit

This flag is not implemented for J2EE 1.4 Application Server.

lock-when-loaded

An exclusive lock is obtained when the data is loaded.

lock-when-modified

This flag is not implemented for J2EE 1.4 Application Server.

none

No consistency checking occurs.

ejb-name

Specifies the name of the entity bean in the ejb-jar.xml file to which the container-managed persistence beans relates. One is required.

Subelements

none

entity-mapping

Specifies the mapping a bean to database columns.

Subelements

The following table describes subelements for the entity-mapping element.

Table 3-11  entity-mapping Subelements 

Subelement

Required

Description

ejb-name

only one

Specifies the name of the entity bean in the ejb-jar.xml file to which the container-managed persistence beans relates. One is required.

table-name

only one

Specifies the name of a database table. The table must be present in the database schema file.

cmp-field-mapping

one or more

Associates a field with one or more columns that it maps to. The column can be from a bean’s primary table or any defined secondary table. If a field is mapped to multiple columns, the column listed first is used as a SOURCE for getting the value from the database. The columns are updated in the order they appear. There is one cmp-field-mapping element for each cmp-field element defined in the EJB JAR file.

A field can be marked as read-only.

cmr-field-mapping

zero or more

A container-managed relationship field has a name and one or more column pairs that define the relationship. There is one cmr-field-mapping element for each cmr-field. A relationship can also participate in a fetch group.

secondary-table

zero or more

Describes the relationship between a bean’s primary and secondary table. Column pairs are used to describe this relationship.

consistency

zero or one

Specifies container behavior in guaranteeing transactional consistency of the data in the bean. If the consistency checking flag element is not present, none is assumed.

fetched-with

Specifies the fetch group configuration for fields and relationships. Optional. The fetched-with element has different default values based on its parent element.

Subelements

The following table describes subelements for the fetched-with element.

Table 3-12  fetched-with Subelements 

Subelement

Required

Description

level

exactly one of these elements is required

Specifies the name of a hierarchical fetch group. The name must be an integer. Fields and relationships that belong to a hierarchical fetch group of equal (or lesser) value are fetched at the same time. The value of level must be greater than zero.

named-group

Specifies the name of an independent fetch group. All the fields and relationships that are part of a named group are fetched at the same time.

none

A flag that indicates that this field or relationship is fetched by itself.

field-name

Specifies the Java identifier of a field. This identifier must match the value of the field-name subelement of the cmp-field that is being mapped. One is required.

Subelements

none

level

Specifies the name of a hierarchical fetch group. The name must be an integer. Fields and relationships that belong to a hierarchical fetch group of equal (or lesser) value are fetched at the same time. The value of level must be greater than zero. Only one is allowed.

Subelements

none

lock-when-loaded

Places a database update lock on the rows corresponding to the bean whenever the bean is loaded. The lock is placed by issuing SELECT ... FOR UPDATE. The lock is released when the transaction finishes (commit or rollback). While the lock is placed, other database users have read access to the bean.

Subelements

none

lock-when-modified

This flag is not implemented for J2EE 1.4 Application Server.

Subelements

none

named-group

Specifies the name of an independent fetch group. All the fields and relationships that are part of a named group are fetched at the same time. One is allowed.

Subelements

none

none

A consistency level flag that indicates that this field or relationship is fetched with no other fields or relationships, or it specifies the fetched-with semantics.

Subelements

none

read-only

Flag that indicates a field is read-only.

Subelements

none

schema

Specifies the path to the schema file if the file was manually generated. The path is relative to the directory containing the sun-cmp-mappings.xml file, and the file name omits the .dbschema extension. To use automatic schema generation, do not specify a value for this element. For example:

<schema>RosterSchema</schema> <!-- named schema>

<schema></schema> <!-- use automatic schema generation>

Subelements

none

secondary-table

Specifies a bean’s secondary table(s).

Subelements

The following table describes subelements for the secondary-table element.

Table 3-13  secondary table Subelements 

Subelement

Required

Description

table-name

only one

Specifies the name of a database table. The table must be present in the database schema file.

column-pair

one or more

The name of the pair of related columns in two database tables.

sun-cmp-mapping

Specifies beans mapped to a particular schema.


Note

A bean cannot be related to a bean that maps to a different schema, even if the beans are deployed in the same EJB JAR file.


Subelements

The following table describes subelements for the sun-cmp-mapping element.

Table 3-14  sun-cmp-mapping Subelements 

Subelement

Required

Description

schema

only one

Specifies the path to the schema file.

entity-mapping

one or more

Specifies the mapping of beans to database columns.

sun-cmp-mappings

Specifies the collection of subelements for all the beans that will be mapped in an EJB JAR collection.

Subelements

The following table describes subelements for the sun-cmp-mappings element.

Table 3-15  sun-cmp-mappings Subelements 

Subelement

Required

Description

sun-cmp-mapping

one or more

Specifies beans mapped to a particular schema.

table-name

Specifies the name of a database table. The table must be present in the database schema file. One is required.

Subelements

none


Examples

The following examples are contained in this section:

Sample Schema Definition

CREATE TABLE Player
(
  player_Id VARCHAR(255) PRIMARY KEY,
  name VARCHAR(255),
  position VARCHAR(255),
  salary DOUBLE PRECISION NOT NULL,
  picture BLOB,
);

CREATE TABLE League
(
  league_Id VARCHAR(255) PRIMARY KEY,
  name VARCHAR(255),
  sport VARCHAR(255),
);

CREATE TABLE Team
(
  team_Id VARCHAR(255) PRIMARY KEY,
  city VARCHAR(255),
  name VARCHAR(255),
  league_Id VARCHAR(255),
  FOREIGN KEY (league_Id) REFERENCES League (league_Id),
);

CREATE TABLE TeamPlayer
(
  player_Id VARCHAR(255),
  team_Id VARCHAR(255),
  CONSTRAINT pk_TeamPlayer PRIMARY KEY (player_Id, team_Id),
  FOREIGN KEY (team_Id) REFERENCES Team (team_Id),
  FOREIGN KEY (player_Id) REFERENCES Player (player_Id),
);

Sample CMP Mapping XML File

For information on these elements, refer to "Elements in the sun-cmp-mappings.xml File".

The following sample mapping file would have the name META-INF/sun-cmp-mappings.xml in a deployable EJB JAR file:

<?xml version="1.0" encoding="UTF-8"?>
<sun-cmp-mappings>
  <sun-cmp-mapping>
    <schema>RosterSchema</schema>
    <entity-mapping>
      <ejb-name>League</ejb-name>
      <table-name>League</table-name>
      <cmp-field-mapping>
        <field-name>name</field-name>
        <column-name>League.name</column-name>
      </cmp-field-mapping>
      <cmp-field-mapping>
        <field-name>leagueId</field-name>
        <column-name>League.league_Id</column-name>
      </cmp-field-mapping>
      <cmp-field-mapping>
        <field-name>sport</field-name>
        <column-name>League.sport</column-name>
      </cmp-field-mapping>
      <cmr-field-mapping>
        <cmr-field-name>team</cmr-field-name>
        <column-pair>
          <column-name>League.league_Id</column-name>
          <column-name>Team.league_Id</column-name>
        </column-pair>
      </cmr-field-mapping>
    </entity-mapping>
    <entity-mapping>
      <ejb-name>Team</ejb-name>
      <table-name>Team</table-name>
      <cmp-field-mapping>
        <field-name>name</field-name>
        <column-name>Team.name</column-name>
      </cmp-field-mapping>
      <cmp-field-mapping>
        <field-name>city</field-name>
        <column-name>Team.city</column-name>
      </cmp-field-mapping>
      <cmp-field-mapping>
        <field-name>teamId</field-name>
        <column-name>Team.team_Id</column-name>
      </cmp-field-mapping>
      <cmr-field-mapping>
        <cmr-field-name>playerId</cmr-field-name>
        <column-pair>
          <column-name>Team.team_Id</column-name>
          <column-name>TEAMPLAYER.team_Id</column-name>
        </column-pair>
        <column-pair>
          <column-name>TEAMPLAYER.player_Id</column-name>
          <column-name>Player.player_Id</column-name>
        </column-pair>
        <fetched-with>
          <none/>
        </fetched-with>
      </cmr-field-mapping>
      <cmr-field-mapping>
        <cmr-field-name>leagueId</cmr-field-name>
        <column-pair>
          <column-name>Team.league_Id</column-name>
          <column-name>League.league_Id</column-name>
        </column-pair>
        <fetched-with>
          <none/>
        </fetched-with>
      </cmr-field-mapping>
    </entity-mapping>
    <entity-mapping>
      <ejb-name>Player</ejb-name>
      <table-name>Player</table-name>
      <cmp-field-mapping>
        <field-name>salary</field-name>
        <column-name>Player.salary</column-name>
      </cmp-field-mapping>
      <cmp-field-mapping>
        <field-name>playerId</field-name>
        <column-name>Player.player_Id</column-name>
      </cmp-field-mapping>
      <cmp-field-mapping>
        <field-name>position</field-name>
        <column-name>Player.position</column-name>
      </cmp-field-mapping>
      <cmp-field-mapping>
        <field-name>name</field-name>
        <column-name>Player.name</column-name>
      </cmp-field-mapping>
      <cmr-field-mapping>
        <cmr-field-name>teamId</cmr-field-name>
        <column-pair>
          <column-name>Player.player_Id</column-name>
          <column-name>TEAMPLAYER.player_Id</column-name>
        </column-pair>
        <column-pair>
          <column-name>TEAMPLAYER.team_Id</column-name>
          <column-name>Team.team_Id</column-name>
        </column-pair>
      </cmr-field-mapping>
    </entity-mapping>
  </sun-cmp-mapping>
</sun-cmp-mappings>



Previous      Contents      Index      Next     


Copyright 2003 Sun Microsystems, Inc. All rights reserved.