Oracle® Containers for J2EE Enterprise JavaBeans Developer's Guide 10g Release 3 (10.1.3) B14428-02 |
|
![]() Previous |
![]() Next |
This chapter describes the various options that you must configure in order to use an EJB 2.1 CMP entity bean.
Table 14-1 lists these options and indicates which are basic (applicable to most applications) and which are advanced (applicable to more specialized applications).
For more information, see:
Table 14-1 Configurable Options for an EJB 2.1 CMP Entity Bean
Every EJB 2.1 CMP entity bean must have a primary key field.
You can configure the primary key as a well-known Java type (see "Configuring an EJB 2.1 CMP Entity Bean Primary Key Field") or as a special type that you create (see "Configuring an EJB 2.1 CMP Entity Bean Composite Primary Key Class").
You can either assign primary key values yourself, or, more typically, you can associate a primary key field with a primary key value generator (see "Configuring EJB 2.1 CMP Entity Bean Automatic Primary Key Generation").
For a simple EJB 2.1 CMP entity bean, you can define your primary key to be a well-known Java type as follows:
Code your bean's ejbCreate
method to return the primary key class type (see "Implementing an EJB 2.1 Entity Bean")
Configure your deployment XML to use it (see "Using Deployment XML")
Once defined, the container may create a column or columns in the entity bean table for the primary key and maps the primary key defined in the deployment descriptor to this column.
Once this configuration is complete, the container manages the instantiation of primary keys of this type and initializes your entity bean primary key field accordingly.
If you specify your primary key type as java.lang.Object, you can rely on the container to automatically handle the allocation of primary key values (see "Configuring EJB 2.1 CMP Entity Bean Automatic Primary Key Generation").
Example 14-1 shows the ejb-jar.xml
file entity
element attributes prim-key-class
and primkey-field
configured to specify a primary key as well-known Java type Integer
.
Example 14-1 ejb-jar.xml for Primary Key Field with Type Integer
<enterprise-beans> <entity> <display-name>Employee</display-name> <ejb-name>EmployeeBean</ejb-name> <local-home>employee.EmployeeLocalHome</local-home> <local>employee.EmployeeLocal</local> <ejb-class>employee.EmployeeBean</ejb-class> <persistence-type>Container</persistence-type> <prim-key-class>java.lang.Integer</prim-key-class> <reentrant>False</reentrant> <cmp-version>2.x</cmp-version> <abstract-schema-name>Employee</abstract-schema-name> <cmp-field><field-name>empNo</field-name></cmp-field> <cmp-field><field-name>empName</field-name></cmp-field> <cmp-field><field-name>salary</field-name></cmp-field> <primkey-field>empNo</primkey-field> </entity> ... </enterprise-beans>
Within the orion-ejb-jar.xml
file, the primary key is mapped to the underlying database persistence storage by mapping the CMP field or primary key field defined in the ejb-jar.xml
file to the database column name. Example 14-2 shows the EmpBean
persistence storage is defined as the EMP
table in the database that is defined in the jdbc/OracleDS
data source. Following the <entity-deployment>
element definition, the primary key, empNo
, is mapped to the EMPNO
column in the Emp
table, and the empName
and salary
CMP fields are mapped to EMPNAME
and SALARY
columns respectively in the EMP
table.
Example 14-2 orion-ejb-jar.xml for Primary Key Field
<entity-deployment name="EmployeeBean" ...table="EMP" data-source="jdbc/OracleDS"... > <primkey-mapping> <cmp-field-mapping name="empNo" persistence-name="EMPNO" /> </primkey-mapping> <cmp-field-mapping name="empName" persistence-name="EMPNAME" /> <cmp-field-mapping name="salary" persistence-name="SALARY" /> ...
If your primary key is more complex than a well-known Java data type, then you can define your own primary key class.
Your primary key class must have the following characteristics:
be named <
name
>PK
be public
and serializable
provide a constructor for creating a primary key instance
Your class may contain any number of instance variables used to form the primary key. Instance variables must have the following characteristics:
be public
use data types that are either primitive or serializable, or types that can be mapped to SQL types
Once the primary key class is defined (see "Using Java"), to use it in an EJB, you must:
Code your bean's ejbCreate
method to return the primary key class type (see "Implementing an EJB 2.1 Entity Bean")
Configure your deployment XML to use it (see "Using Deployment XML")
Once this configuration is complete, the container manages the instantiation of primary keys of this type and initializes your entity bean primary key field accordingly.
Example 14-3 shows an example primary key class.
Example 14-3 EJB 2.1 CMP Entity Bean Primary Key Class Implementation
package employee; import java.io.*; import java.io.Serializable; ... public class EmployeePK implements java.io.Serializable { public Integer empNo; public EmployeePK() { this.empNo = null; } public EmployeePK(Integer empNo) { this.empNo = empNo; } }
As Example 14-4 shows, you define the primary key class within the ejb-jar.xml
file <prim-key-class>
element. You define each primary key class instance variable in a <cmp-field><field-name>
element using the same variable name as that used in the primary key class.
Example 14-4 ejb-jar.xml For a Primary Key Class and Its Instance Variables
<enterprise-beans>
<entity>
<description>no description</description>
<display-name>EmployeeBean</display-name>
<ejb-name>EmployeeBean</ejb-name>
<local-home>employee.LocalEmployeeHome</home>
<local>employee.LocalEmployee</remote>
<ejb-class>employee.EmployeeBean</ejb-class>
<persistence-type>Container</persistence-type>
<prim-key-class>employee.EmployeePK</prim-key-class>
<reentrant>False</reentrant>
<cmp-version>2.x</cmp-version>
<abstract-schema-name>Employee</abstract-schema-name>
<cmp-field><field-name>empNo</field-name></cmp-field>
<cmp-field><field-name>empName</field-name></cmp-field>
<cmp-field><field-name>salary</field-name></cmp-field>
</entity>
</enterprise-beans>
Once defined, the container may create a column or columns in the entity bean table for the primary key and maps the primary key class defined in the deployment descriptor to this column.
The CMP fields are mapped in the orion-ejb-jar.xml
in the same manner as described in "Configuring an EJB 2.1 CMP Entity Bean Primary Key Field". However, with a complex primary key, the mapping contains more than a single field; thus, the <primkey-mapping>
<cmp-field-mapping>
element contains another subelement: the <fields>
element. All of the fields of a primary key are each defined in a separate <cmp-field-mapping>
element within the <fields>
element, as Example 14-5 shows.
If you specify the type of your primary key field (see "Configuring an EJB 2.1 CMP Entity Bean Primary Key Field") as java.lang.Object
but do not specify the primary key name, then the primary key is auto-generated by the container (see "Using Deployment XML").
Example 14-6 shows the ejb-jar.xml
for an unnamed primary key field of type Object
.
Example 14-6 ejb-jar.xml for Primary Key Field with Type Object
<enterprise-beans>
<entity>
<display-name>Employee</display-name>
<ejb-name>EmployeeBean</ejb-name>
<local-home>employee.EmployeeLocalHome</local-home>
<local>employee.EmployeeLocal</local>
<ejb-class>employee.EmployeeBean</ejb-class>
<persistence-type>Container</persistence-type>
<prim-key-class>java.lang.Object</prim-key-class>
<reentrant>False</reentrant>
<cmp-version>2.x</cmp-version>
<abstract-schema-name>Employee</abstract-schema-name>
<cmp-field><field-name>empNo</field-name></cmp-field>
<cmp-field><field-name>empName</field-name></cmp-field>
<cmp-field><field-name>salary</field-name></cmp-field>
</entity>
...
</enterprise-beans>
Once defined, the container creates a column in the entity bean table for the primary key of type LONG
. The container uses random numbers for the primary key values. This is generated in the orion-ejb-jar.xml
for the bean as Example 14-7. In this case, the container will create a column named autoid
.
You can configure OC4J to automatically create (and, optionally, delete) database tables for your persistent objects (see "Using Deployment XML").
You can use this feature in conjunction with default mappings (see "Configuring Default Mappings").
You can configure automatic database table creation at one of three levels as Table 14-2 shows. You can override the system level configuration at the application level and you can override system and application configuration at the EJB module level.
Table 14-2 Configuring Automatic Table Generation
Level | Configuration File | Setting | Values |
---|---|---|---|
System (global) |
|
|
|
Application (EAR) |
|
|
|
EJB Module (JAR) |
|
|
|
Footnote 1 Default.
Footnote 2 For more information, see "Customizing the TopLink Persistence Manager".
Footnote 3 See Table 14-3.
If you configure automatic table generation at the EJB module level, the value you assign to the db-table-gen
attribute corresponds to the autocreate-tables
and autodelete-tables
settings as Table 14-3 shows.
You do not define CMP fields in the entity bean class: CMP fields are virtual only. OC4J supplies the implementation of the CMP fields.
You must define public
, abstract
get and set methods for the CMP fields, using the JavaBeans conventions (see "Using Java"). OC4J supplies the implementation of these methods. You must not expose these get and set methods in the remote interface of the entity bean.
You may assign only the following Java types to CMP fields: Java primitive types and Java serializable types. You may not assign an entity bean local interface type (or a collection of such) to a CMP field.
The container-managed persistent fields must be specified in the ejb-jar.xml
deployment descriptor using the cmp-field
element (see "Using Deployment XML"). The names of these fields must be valid Java identifiers and must begin with a lowercase letter, as determined by java.lang.Character.isLowerCase
.
The accessor methods must bear the name of the cmp-field
that is specified in the deployment descriptor, and in which the first letter of the name of the cmp-field has been upper cased and prefixed by get
or set
.
For more information, see "What are Container-Managed Persistence Fields?".
Example 14-8 shows the abstract get and set methods for the CMP fields specified in the ejb-jar.xml
file (see "Using Deployment XML").
Example 14-8 EJB 2.1 Container-Managed Persistence Fields
package cmpapp; import javax.ejb.*; import java.rmi.*; public abstract class EmployeeBean implements EntityBean { private EntityContext ctx; // cmp fields accessors public abstract Integer getEmpNo(); public abstract void setEmpNo(Integer empNo); public abstract String getEmpName(); public abstract void setEmpName(String empName); public abstract Float getSalary(); public abstract void setSalary(Float salary); ... }
Example 14-9 shows the cmp-field
elements for the get and set methods specified in the bean class (see "Using Java").
Example 14-9 ejb-jar.xml for an EJB 2.1 CMP Field
<enterprise-beans> <entity> <ejb-name>Topic</ejb-name> <local-home>faqapp.TopicLocalHome</local-home> <local>faqapp.TopicLocal</local> <ejb-class>faqapp.TopicBean</ejb-class> <persistence-type>Container</persistence-type> <prim-key-class>java.lang.Integer</prim-key-class> <primkey-field>topicID</primkey-field> <reentrant>False</reentrant> <cmp-version>2.x</cmp-version> <abstract-schema-name>TopicBean</abstract-schema-name> <cmp-field> <field-name>topicID</field-name> </cmp-field> <cmp-field> <field-name>topicDesc</field-name> </cmp-field> ... </entity> </enterprise-beans>
You do not define CMR fields in the entity bean class: CMR fields are virtual only. OC4J supplies the implementation of the CMR fields.
You must define public
, abstract
get and set methods for the CMR fields in the local interface of the related entity bean, using the JavaBeans conventions (see "Using Java"). OC4J supplies the implementation of these methods. You must not expose these get and set methods in the remote interface of the entity bean.
You may assign only the following Java types to CMP fields: Java primitive types and Java serializable types. You may assign an entity bean local interface type (or a collection of such) to a CMR field.
You must specify container-managed relationship fields in the ejb-jar.xml
deployment descriptor using the cmr-field
element (see "Using Deployment XML"). The names of these fields must be valid Java identifiers and must begin with a lowercase letter, as determined by java.lang.Character.isLowerCase.
The accessor methods must bear the name of the container-managed relationship field (cmr-field
) that is specified in the deployment descriptor, and in which the first letter of the name of the cmr-field
has been upper cased and prefixed by get
or set
.
The accessor methods for CMR fields for one-to-many or many-to-many relationships must utilize one of the following collection interfaces: java.util.Collection
or java.util.Set
. The collection interfaces used in relationships are specified in the deployment descriptor. The implementation of the collection classes used for the CMR fields is supplied by the container. The collection classes that are used for container-managed relationships must not be exposed through the remote interface of the entity bean.
For more information, see:
Example 14-10 shows the abstract get and set methods for the CMR fields specified in the ejb-jar.xml
file (see "Using Deployment XML").
Example 14-10 EJB 2.1 Container-Managed Relationship Fields
package cmpapp; import javax.ejb.*; import java.rmi.*; public abstract class EmployeeBean implements EntityBean { private EntityContext ctx; // cmp fields accessors public abstract Integer getEmpNo(); public abstract void setEmpNo(Integer empNo); public abstract String getEmpName(); public abstract void setEmpName(String empName); public abstract Float getSalary(); public abstract void setSalary(Float salary); public abstract void setProjects(Collection projects); public abstract Collection getProjects(); ... }
Example 14-11 shows the cmr-field
elements for the get and set methods specified in the bean class (see "Using Java").
Example 14-11 ejb-jar.xml for an EJB 2.1 CMR Field
... <relationships> <ejb-relation> <ejb-relation-name>Topic-Faqs</ejb-relation-name> <ejb-relationship-role> <ejb-relationship-role-name>Topic-has-Faqs</ejb-relationship-role-name> <multiplicity>Many</multiplicity> <relationship-role-source> <ejb-name>TopicBean</ejb-name> </relationship-role-source> <cmr-field> <cmr-field-name>faqs</cmr-field-name> <cmr-field-type>java.util.Collection</cmr-field-type> </cmr-field> </ejb-relationship-role> <ejb-relation> ... <relationships>
You can configure OC4J to automatically generate all required mappings at deployment time (see "Using Deployment XML"). To use this feature, you must:
Omit all container-managed relationship configuration (see "Configuring an EJB 2.1 CMP Entity Bean Container-Managed Persistence Field").
Ensure that no toplink-ejb-jar.xml
is present in the EJB module (see "What is the toplink-ejb-jar.xml File?").
You can use this feature in conjunction with automatic database table creation (see "Configuring Automatic Database Table Creation").
To configure default mapping, configure the orion-ejb-jar.xml
file element pm-properties
subelement default-mapping
as Table 14-4 shows.
Table 14-4 orion-ejb-jar.xml File pm-properties Subentries for default-mapping
Entry | Description |
---|---|
|
Optional element that determines what TopLink will do to prepare the database tables that are being mapped to. Valid values are:
If no The This setting overrides autocreate-tables and autodelete-tables configuration at the application (EAR) or system level. For more information, see "Configuring Automatic Database Table Creation". |
|
An element used if the generated table names are not long enough to be unique. Values are restricted to In default mapping, each entity is mapped to one table. The only exception is in many-to-many mappings where there is one extra relation table involved in the source and target entities. When However, if the same entity is defined in multiple JAR files in an application, or across multiple applications, table-naming collision is inevitable. To address this problem, set If there is no The |
Each finder method retrieves one or more objects. In the default scenario (which is set to NO lazy loading), the finder method causes a single SQL select statement to be executed against the database. For a CMP bean, one or more objects are retrieved with all of their CMP fields. So, for example, with the findAllEmployees
method, this finder retrieves all employee objects with all of the CMP fields in each employee object.
If you turn on lazy loading, then only the primary keys of the objects retrieved within the finder are returned. Then, only when you access the object within your implementation, OC4J uploads the actual object based on the primary key. With the findAllEmployees
finder method example, all of the employee primary keys are returned in a Collection
. The first time you access one of the employees in the Collection
, OC4J uses the primary key to retrieve the single employee object from the database. You may want to turn on the lazy loading feature if the number of objects that you are retrieving is so large that loading them all into your local cache would be a performance degradation.
You have a performance consideration with lazy loading. If you retrieve multiple objects, but you only use a few of them, then you should turn on lazy loading. In addition, if you only use objects through the getPrimaryKey
method, then you should also turn on lazy loading.
To turn on lazy loading in the findByPrimaryKey
method, set the findByPrimaryKey-lazy-loading
attribute to true, as follows:
<entity-deployment ... findByPrimaryKey-lazy-loading="true" ... >
To turn on lazy loading in any custom finder method, set the lazy-loading attribute to true in the <finder-method>
element for that custom finder, as follows:
<finder-method ... lazy-loading="true" ...> ... </finder-method>
Note: If you set this attribute to true, themin/max-instances-per-pk attribute is ignored. |