Skip Headers

Oracle9iAS Containers for J2EE Enterprise JavaBeans Developer's Guide
Release 2 (9.0.3)

Part Number A97677-01
Go To Core Documentation
Core
Go To Platform Documentation
Platform
Go To Table Of Contents
Contents
Go To Index
Index

Go to previous page Go to next page

4
Entity Relationship Mapping

This chapter discusses how to develop entity-to-entity relationships. As a developer, you can approach entity relationships from either the EJB development or database development viewpoint.

This chapter starts by discussing entity relationships from the EJB development viewpoint. Next, it demonstrates how the deployment descriptor maps to database tables. If you want to design with the database development viewpoint, skip to "Mapping Relationship Fields to the Database".

This chapter covers the following topics:

Defining Entity-To-Entity Relationships

The following sections describe what an entity bean relationship can be and how to define them.

Choosing Cardinality and Direction

Cardinality refers to the number of entity objects on each side of the relationship. Thus, you can define the following types of relationship between EJBs:

In addition, each relationship can be one-way or two-way. This is referred to as the direction of the relationship. The one-way relationship is unidirectional; the two-way relationship is bidirectional. For example, a unidirectional relationship can be from an employee to an address. With the employee information, you can retrieve an address. However, with an address, you cannot retrieve the employee. An example of a bidirectional relationship is with a employee/projects example. Given a project number, you can retrieve the employees working on the project. Given an employee number, you can retrieve all projects that the employee is working on. Thus, the relationship is valid in both directions.

Normally, you use a unidirectional relationship when you want to reuse the target from multiple entities.

You define the cardinality and direction of the relationship between two beans in the deployment descriptor.

One-To-One Relationship Overview

A one-to-one relationship is the simplest relationship between two beans. One entity bean relates only to one other entity bean. If our company office contains only cubicles, and only a single employee can sit in each cubicle, then you have a one-to-one relationship: one employee in one designated cubicle. You define a unidirectional definition for this relationship as follows:

employee --> cubicle

However, if you have a cubicle number and want to determine who is assigned to it, you can assign a bidirectional relationship. This would enable you to retrieve the employee and find what cubicle he/she sits in. In addition, you could retrieve the cubicle number and determine who sits there. You define this bidirectional one-to-one relationship as follows:

employee <--> cubicle

One-To-Many or Many-To-One Relationship Overview

In a one-to-many relationship, one object can reference several instances of another. A many-to-one relationship is when many objects reference a single object. For example, an employee can have multiple addresses: a home address and an office address. If you define these relationships as unidirectional from the perspective of the employee, then you can look up the employee and see all of his/her addresses, but you cannot look up an address to see who lives there. However, if you define this relationship as bidirectional, then you can look up any address and see who lives there.

Many-To-Many Relationship Overview

A many-to-many relationship is complex. For example, each employee can be working on several projects. And each projects has multiple employees working on it. Thus, you have a many-to-many cardinality. The direction does not matter in this instance. You have the following cardinality:

employees <--> projects

In a many-to-many relationship, many objects can reference many objects. This cardinality is the most difficult to manage.

Defining Relationships

Here are the restrictions imposed on defining your relationships:

The following are the requirements to define each cardinality type and its direction:

  1. Define the abstract accessor methods (get/set methods) for each relationship field. The naming follows the same rules as for the persistence field abstract accessor methods. For example, getAddress and setAddress methods are abstract accessor methods for retrieving and setting an address.

  2. Define each relationship--its cardinality and direction--in the deployment descriptor. The relationship field name is defined in the <cmr-field-name> element. This name must be the same as the abstract accessor methods, without the get/set and the first letter in lower case. For example, the <cmr-field-name> would be address to compliment the getAddress/setAddress abstract accessor methods.

  3. Declare if you want the cascade delete option for the one-to-one, one-to-many, and many-to-one relationships. The cascade delete is always specified on the "one" side of the relationship.

Define the Get/Set Methods for Each Relationship Field

Each relationship field must have the abstract accessor methods defined for it. In a relationship that sets or retrieves only a single entity, the object type passed back and forth must be the local interface of the target entity bean. In a relationship that sets or retrieves multiple objects, the object type passed back and forth is a Set or Collection containing local interface objects.

Example 4-1 Definition of Abstract Accessor Methods for the Employee Example

In this example, the employee can have only a single address, and you can retrieve the address only through the employee. This defines a one-to-one relationship that is unidirectional from the perspective of the employee. Then the abstract accessor methods for the employee bean are as follows:

public AddressLocal getAddress();
public void setAddress(AddressLocal address);

Because the cardinality is one-to-one, the local interface of the address entity bean is the object type that is passed back and forth in the abstract accessor methods.

The cardinality and direction of the relationship are defined in the deployment descriptor.

Example 4-2 Definition of One-To-Many Abstract Accessor Methods

If the employee example included a one-to-many relationship, the abstract accessor methods would pass back and forth a Set or Collection of objects, each of which contains target bean local interface objects. When you have a "many" relationship, multiple records are being passed back and forth.

A department contains many employees. In this one-to-many example, the abstract accessor methods for the department retrieves multiple employees. Thus, the abstract accessor methods pass a Collection or a Set of employees, as follows:

public Collection getDeptEmployees();
public void setDeptEmployees(Collection deptEmpl);

Declare the Relationships in the Deployment Descriptor

You define the relationships between entity beans in the same deployment descriptor the entity beans are declared. All entity-to-entity relationships are defined within the <relationships> element and you can define multiple relationships within this element. Each specific entity-to-entity relationship is defined within an <ejb-relation> element. The following XML demonstrates two entity-to-entity relationships defined within an application:

<relationships>
      <ejb-relation>
      ...
      </ejb-relation>
      <ejb-relation>
      ...
      </ejb-relation>
</relationships>

The following XML shows the full element structure for relationships:

<relationships>
  <ejb-relation>
    <ejb-relation-name> </ejb-relation-name>
    <ejb-relationship-role>
      <ejb-relationship-role-name> </ejb-relationship-role-name>
      <multiplicity> </multiplicity>
      <relationship-role-source>
         <ejb-name> </ejb-name>
      </relationship-role-source>
      <cmr-field>
        <cmr-field-name> </cmr-field-name>
        <cmr-field-type> </cmr-field-type>
      </cmr-field>
    </ejb-relationship-role>
  </ejb-relation>
</relationships>

Table 4-1 describes the usage for each of these elements.

Table 4-1 Description of Relationship Elements of the Deployment Descriptor

Deployment Descriptor Element Description

<ejb-relation>

Each entity-to-entity relationship is described in a single <ejb-relation> element.

<ejb-relation-name>

A user-defined name for the entity-to-entity relationship.

<ejb-relationship-role>

Each entity within the relationship is described within its own <ejb-relationship-role>. Thus, there are always two <ejb-relationship-role> entities within the <ejb-relation>.

<ejb-relationship-role-name>

A user-defined name to describe the role or involvement of the entity bean in the relationship.

<multiplicity>

The declaration of the cardinality for this entity. The value is "one" or "many."

<relationship-role-source><ejb-name>

The name of the entity bean. This must equal an EJB name defined in an <entity><ejb-name> element.

<cmr-field><cmr-field-name>

A user-defined name to represent the target bean reference. This name must match the abstract accessor methods. For example, if the abstract accessor fields are getAddress() and setAddress(), the CMR field must be address.

<cmr-field><cmr-field-type>

Optional. If "many", this type should be a Collection or Set. This is only specified for the "many" side to inform if a Collection or a Set is returned.

These relationships can be one-to-one, one-to-many, or many-to-many. The cardinality is defined within the <multiplicity> element. Each bean defines its cardinality within its own relationship. For example,

The direction of the relationship is defined by the presence of the <cmr-field> element. The reference to the target entity is defined within the <cmr-field>. If you are unidirectional, then only one entity within the relationship contains a reference to a target. In this case, the <cmr-field> is declared in the source entity and contains the target bean reference. If bidirectional, both entities should declare each other's target bean references within a <cmr-field> element.

The following demonstrates how to declare direction in the one-to-one employee and address example:

Once you understand how to declare the cardinality and direction of the entity relationships, configuring the deployment descriptor for each relationship is simple.

Example 4-3 One-To-One Relationship Example

The employee example defines a one-to-one unidirectional relationship in which each employee has only one address. This relationship is unidirectional because you can retrieve the address from the employee, but you cannot retrieve the employee from the address. Thus, the employee object has a relationship to the address object.

In the deployment descriptor, you configure the following:

Decide Whether to Use the Cascade Delete Option

When you have relationships between entity beans and the master entity bean is deleted, what happens to the slave beans? This question is answered by the cascade delete option. If you specify cascade delete to happen, the deletion of a master entity causes the deletion of all its slave relationship entity beans.

The cascade delete is defined in the object that is deleted automatically.

For example, an employee has a relationship with an address object. The employee object specifies cascade delete. When the employee, as master in this relationship, is deleted, the address, the slave, is also deleted.

In some instances, you do not want a cascade delete to occur. If you have a department that has a relationship with multiple employees within the department, you do not want all employees to be deleted when you delete the department.

You can only specify a cascade delete on a relationship if the master entity bean has a <multiplicity> of one. Thus, in a one-to-one, the master is obviously a "one". You can specify a cascade delete in a one-to-many relationship, but not in a many-to-one or many-to-many relationship.

The cascade delete is specified in the slave entity bean of the one-to-one or one-to-many relationship. Thus, when the master entity bean is deleted, the slave entity beans are deleted.

Example 4-4 Cascade Delete Requested in the Employee Example

The following deployment descriptor shows the definition of a one-to-one relationship with the employee and his/her address. When the employee is deleted, the slave entity bean--the address--is automatically deleted. You ensure the deletion by specifying the <cascade-delete/> element in the slave entity bean of the relationship. In this case, specify the <cascade-delete/> element in the AddressBean definition.

<relationships>
   <ejb-relation>
         <ejb-relation-name>Emp-Address</ejb-relation-name>
         <ejb-relationship-role>
            <ejb-relationship-role-name>Emp-has-Address
            </ejb-relationship-role-name>
            <multiplicity>One</multiplicity>
            <relationship-role-source><ejb-name>EmpBean</ejb-name>
            </relationship-role-source>
            <cmr-field>
               <cmr-field-name>address</cmr-field-name>
            </cmr-field>
         </ejb-relationship-role>
         <ejb-relationship-role>
            <ejb-relationship-role-name>Address-has-Emp
            </ejb-relationship-role-name>
            <multiplicity>One</multiplicity>
           <cascade-delete/>
            <relationship-role-source><ejb-name>AddressBean</ejb-name>
            </relationship-role-source>
         </ejb-relationship-role>
      </ejb-relation>
</relationships>

Mapping Relationship Fields to the Database

Each entity bean maps to a table in the database. Each of its persistent and relationship fields are saved within a database table in columns. For these fields to be mapped to a database, do one of the following:

Default Mapping of Relationship Fields to the Database


Note:

This section discusses how OC4J maps relationship fields to the database. Chapter 3, "CMP Entity Beans" discusses persistent field mapping.


If you declare relationship fields only in the ejb-jar.xml file, then OC4J provides default mappings of these fields to the database. The default mapping is the same as for the persistent fields, as described in "Default Mapping of Persistent Fields to the Database". describes.


Note:

For all future redeployments, copy the generated orion-ejb-jar.xml file with this table name into the same directory as your ejb-jar.xml file. Thus, all future redeployments have the same table names as first generated. If you do not copy this file over, different table names may be generated.


In summary, these defaults include:

Default Mapping of the One-To-One Relationship

The one-to-one entity relationship is managed between the entity tables with a foreign key. Figure 4-1 demonstrates a one-to-one unidirectional relationship between the employee and address bean.


Note:

Normally, you use a unidirectional relationship when you want to reuse the target for multiple entities. To reuse a table in the database, the target table must have the same definition for all tables using it. The target table does not normally have a foreign key pointing back to any of the source tables. For this reason, when you reuse a table, it is normally the target of a unidirectional relationship.


Figure 4-1 One-To-One Employee Relationship Example

Text description of ormapa.gif follows

Text description of the illustration ormapa.gif

Default Mapping of One-To-Many and Many-To-Many Relationships

You cannot facilitate the one-to-many and many-to-many relationships using only a primary key and foreign key in the entity tables. To facilitate these relationships, the container creates an association table. The association table contains two columns, where each contains a foreign key to each of the entity tables in the relationship.

Figure 4-2 shows the tables that are created for the employee/project relationship. Each project can have multiple employees, and each employee can belong to several projects. Thus, the employee and project relationship is a many-to-many relationship. The container creates three tables to manage this relationship: the employee table, the project table, and the association table for both of these tables.

Figure 4-2 Many-To-Many Employee Relationship Example

Text description of ormap4.gif follows

Text description of the illustration ormap4.gif

The association table contains a foreign key column that points to the employee table and a foreign key column that points to the project table. The column names of the association table are a concatenation of the entity bean name in <ejb-name> and its primary key name. If the primary key for the bean is auto-generated, then "autoid" is appended as the primary key name. For example, the foreign key that points to the employee table is the bean name of EmpBean, followed by the primary key name of empno, which results in the column name EmpBean_empno. The foreign key that points to the address table is the bean name of ProjectBean concatenated with autoid, because the primary key is auto-generated, which results in the column name ProjectBean_autoid.

The following is a demonstration of the association table for the employee/projects relationship. Employee 1 is assigned to projects a, b, and c. Project a involves employees 1, 2, and 3. The association table contains the following:

EmpBean_empno ProjectBean_autoid

1

a

1

b

1

c

2

a

3

a

The association table details all relationships between the two entity beans.

Example 4-5 Deployment Descriptor for a Many-To-Many Relationship

To configure the employee/project many-to-many relationship in the deployment description, create an <ejb-relation> in which each bean defines its <multiplicity> as many and defines a <cmr-field> to the other bean of type Collection or Set.

<enterprise-beans>
  <entity>
    ...
    <ejb-name>EmpBean</ejb-name>
    <local-home>employee.EmpHome</local-home>
    <local>employee.Emp</local>
    ...
    <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>
    <prim-key-class>java.lang.Integer</prim-key-class>
    ...
  </entity>
  <entity>
    ...
    <ejb-name>ProjectBean</ejb-name>
    <local-home>employee.ProjectHome</local-home>
    <local>employee.Project</local> 
    ...
    <cmp-field><field-name>projectName</field-name></cmp-field>
    <prim-key-class>java.lang.Object</prim-key-class>
    ...
  </entity>
</enterprise-beans>
<relationships>
  <ejb-relation>
    <ejb-relation-name>Emps-Projects</ejb-relation-name>
    <ejb-relationship-role>
      <ejb-relationship-role-name>Project-has-Emps</ejb-relationship-role-name>
      <multiplicity>Many</multiplicity>
      <relationship-role-source>
        <ejb-name>ProjectBean</ejb-name>
      </relationship-role-source>
      <cmr-field>
        <cmr-field-name>employees</cmr-field-name>
        <cmr-field-type>java.util.Collection</cmr-field-type>
      </cmr-field>
    </ejb-relationship-role> 
    <ejb-relationship-role>
      <ejb-relationship-role-name>Emp-has-Projects</ejb-relationship-role-name>
      <multiplicity>Many</multiplicity>
      <relationship-role-source>
        <ejb-name>EmpBean</ejb-name>
      </relationship-role-source>
      <cmr-field>
        <cmr-field-name>projects</cmr-field-name>
        <cmr-field-type>java.util.Collection</cmr-field-type>
      </cmr-field>
    </ejb-relationship-role>
  </ejb-relation>
</relationships>

The container maps this definition to the following:

Example 4-6 Deployment Descriptor for One-To-Many Bidirectional Relationship

The following XML demonstrates how to configure a single employee who can have multiple phone numbers. You can add another source of the phone numbers table, such as department phone numbers, so that the department entity bean has a one-to-many relationship with the phone number entity bean. This is why the employee to phone numbers relationship is unidirectional.

The employee entity bean, EmpBean, defines a <cmr-field> element designating a Collection of phoneNumbers within the PhoneBean.

<relationships>
  <ejb-relation>
   <ejb-relation-name>Emp-Phone</ejb-relation-name>
   <ejb-relationship-role>
     <ejb-relationship-role-name>Emp-PhoneNumbers</ejb-relationship-role-name>
     <multiplicity>One</multiplicity>
     <relationship-role-source>
        <ejb-name>EmpBean</ejb-name>
     </relationship-role-source>
     <cmr-field>
        <cmr-field-name>phoneNumbers</cmr-field-name>
        <cmr-field-type>java.util.Collection</cmr-field-type>
     </cmr-field>
   </ejb-relationship-role>
   <ejb-relationship-role>
     <ejb-relationship-role-name>Phone-has-Emp</ejb-relationship-role-name>
     <multiplicity>Many</multiplicity>
     <relationship-role-source>
        <ejb-name>PhoneBean</ejb-name>
     </relationship-role-source>
    </ejb-relationship-role>
  </ejb-relation>
</relationships>

The container maps this definition to the following:

Figure 4-3 One-To-Many Relationship Employee Example

Text description of ormap5.gif follows

Text description of the illustration ormap5.gif

Explicit Mapping of Relationship Fields to the Database

As "Default Mapping of Relationship Fields to the Database" discusses, your relationship fields can be automatically mapped to the database tables by the container. However, if you do not want to accept the defaults that OC4J provides for you, then you can map the relationships between entity beans within an existing database table and its columns in the orion-ejb-jar.xml file.


Note:

"Explicit Mapping of Persistent Fields to the Database" discusses how to explicitly map persistent fields. This section builds on that information and shows how the relationship mapping occurs.


For explicit mapping, Oracle recommends that you perform the following steps:

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

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

  2. Copy the container-created orion-ejb-jar.xml file to your development environment.

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

  4. Rearchive and redeploy the application.

How you map relationship fields is dependent on the type of relationship:

Modify elements and attributes of the <entity-deployment> element in the orion-ejb-jar.xml file to explicitly map relationship fields.

The following XML shows the relevant elements and attributes for explicit mapping of a one-to-one relationship:

<entity-deployment name=" " location=" " table=" " data-source=" ">
  <cmp-field-mapping name=" ">
    <entity-ref home=" ">
      <cmp-field-mapping name=" " persistence-name=" " />
    </entity-ref>
  </cmp-field-mapping>
</entity-deployment>

The following XML illustrates the relevant elements and attributes for explicitly identifying the association table for one-to-many or many-to-many:

<entity-deployment name=" " location=" " table=" " data-source=" ">
  <cmp-field-mapping name=" "> 
    <collection-mapping table=" ">
      <primkey-mapping>
        <cmp-field-mapping name=" " persistence-name=" " />
      </primkey-mapping>
      <value-mapping type=" ">
        <cmp-field-mapping>
          <entity-ref home=" ">
            <cmp-field-mapping name=" " persistence-name=" "/>
          </entity-ref>
        </cmp-field-mapping>
      </value-mapping>
    </collection-mapping>
  </cmp-field-mapping>
</entity-deployment>

Element or Attribute Description

<entity-deployment>

  • The name attribute identifies the <ejb-name> of the bean.

  • The location attribute identities the JNDI name of the bean.

  • The table attribute identifies the database table to which this entity bean is mapped.

  • The data-source attribute identifies the database in which the table resides.

<cmp-field-mapping>

Use this element to map a persistent field or a relationship field. For relationship fields, it will contain either an <entity-ref> for a one-to-one mapping or a <collection-mapping> for a one-to-many, many-to-one, or many-to-many relationship.

  • The name attribute identifies the <cmp-field> or <cmr-field> that is to be mapped.

  • The persistence-name attribute identifies the database column, which defaults to the <ejb-name> concatenated with the primary key of that entity bean.

<entity-ref>

Use this element to identify the primary key to which the foreign key points. The target bean and its primary key are identified in this element. The container uses this information to create a foreign key in the source table to point to the target table.

  • The name attribute identifies the bean name defined in <ejb-name>.

  • The <cmp-field-mapping> within this element identifies the target table column name.

<collection-mapping>

Use this element to explicitly map the "many" side of a relationship.

  • The table attribute identifies the association table. In a one-to-many bidirectional relationship, you can specify the table of the "many" in this field to avoid the association table.

This element defines two elements, one for each column in the association table:

  • <primkey-mapping> identifies the first foreign key in the association table.

  • <value-mapping> identifies the second foreign key.

<primkey-mapping>

Within the <collection-mapping>, use this element to identify the first foreign key.

<value-mapping>

Use this element to specify the second foreign key.


Note:

This section first describes in detail how logical names defined in the ejb-jar.xml file relate to those in the orion-ejb-jar.xml file, and then how those logical variables defined in the orion-ejb-jar.xml file relate to the database table and column names. This document specifically chooses different names so that you can see which names must be the same. However, for efficiency and ease, you can make all these names the same. For example, a <cmr-field> defined in the ejb-jar.xml file relates to a persistence-name attribute in the orion-ejb-jar.xml file, which is then translated to a column name. Your configuration is easier if all these names are the same.


One-To-One Relationship Explicit Mapping

Figure 4-1 shows a one-to-one unidirectional relationship between an employee and an address. The employee table has a foreign key that points to the primary key of the employee. A one-to-one bidirectional relationship would add a foreign key to the address table that points to the employee.

<enterprise-beans>
  <entity>
    ...
    <ejb-name>EmpBean</ejb-name>
    <local-home>employee.EmpHome</local-home>
    <local>employee.Emp</local>
    <ejb-class>employee.EmpBean</ejb-class>
    ...
    <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>
    <prim-key-class>java.lang.Integer</prim-key-class>
    ...
  </entity>
  <entity>
    ...
    <ejb-name>AddressBean</ejb-name> 
    <local-home>employee.AddressHome</local-home>
    <local>employee.Address</local>
    <ejb-class>employee.AddressBean</ejb-class>
    ...
    <cmp-field><field-name>addressPK</field-name></cmp-field>
    <cmp-field><field-name>addressDescription</field-name></cmp-field>
    <primkey-field>addressPK</primkey-field>
    <prim-key-class>java.lang.Integer</prim-key-class>
    ...
  </entity>
</enterprise-beans>
<relationshipe>
   <ejb-relation>
         <ejb-relation-name>Emp-Address</ejb-relation-name>
         <ejb-relationship-role>
            <ejb-relationship-role-name>Emp-has-Address
            </ejb-relationship-role-name>
            <multiplicity>One</multiplicity>
            <relationship-role-source><ejb-name>EmpBean</ejb-name>
            </relationship-role-source>
            <cmr-field>
               <cmr-field-name>address</cmr-field-name>
            </cmr-field>
         </ejb-relationship-role>
         <ejb-relationship-role>
            <ejb-relationship-role-name>Address-has-Emp
            </ejb-relationship-role-name>
            <multiplicity>One</multiplicity>
            <relationship-role-source><ejb-name>AddressBean</ejb-name>
            </relationship-role-source>
       </ejb-relationship-role>
      </ejb-relation>
</relationships

The EmpBean requires a foreign key to the AddressBean. Thus, the container modifies the <entity-deployment> element for the EmpBean to include a foreign key to the primary key of the AddressBean. The following mapping for this relationship is located in the orion-ejb-jar.xml file:

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

wrapper="EmpHome_EntityHomeWrapper2" max-tx-retries="3" table="emp"     
data-source="jdbc/OracleDS">
<primkey-mapping> <cmp-field-mapping name="empNo" persistence-name="empno" /> </primkey-mapping> <cmp-field-mapping name="empName" persistence-name="ename" /> <cmp-field-mapping name="salary" persistence-name="sal" /> <cmp-field-mapping name="address"> <entity-ref home="AddressBean"> <cmp-field-mapping name="address" persistence-name="addressPK" /> </entity-ref> </cmp-field-mapping> ... </entity-deployment>

This mapping specifies:

Figure 4-4 displays the relationship mapping of the EmpBean address foreign key to the AddressBean addressPK primary key.

Figure 4-4 Demonstration of Explicit Mapping for a One-To-One Relationship

Text description of ormap3.gif follows

Text description of the illustration ormap3.gif

In summary, an address column in the EmpBean_empl_jar_employee table is a foreign key that points to the primary key, addressPK, in the AddressBean_empl_jar_employee table. For the example in which the AddressBean has an auto-generated primary key, an address column in the EmpBean_empl_jar_employee table is a foreign key that points to the primary key, autoid, in the AddressBean_empl_jar_employee table.

One-To-Many and Many-To-Many Relationship Explicit Mapping

Figure 4-3 shows a one-to-many unidirectional relationship between an employee and his/her phone numbers. Because this involves a "many" in the relationship, an association table is created. The association table is the same whether this is a unidirectional or bidirectional, or one-to-many or many-to-many relationship.

In the ejb-jar.xml file, the cardinality is defined in the <relationships> element. The container knows from this definition whether the relationship is one-to-many or many-to-many. In the orion-ejb-jar.xml file, the mapping of this relationship to an association table is described in a <collection-mapping> element. Because the cardinality is already known, only one entity in the relationship defines the <collection-mapping> element.

In the orion-ejb-jar.xml file for the employee example, the EmpBean <entity-deployment> element defines the <collection-mapping> element to designate a Collection of phone numbers. The <collection-mapping> element defines the association table.

<entity-deployment name="EmpBean" location="emp/EmpBean"
wrapper="EmpHome_EntityHomeWrapper2" max-tx-retries="3" 
table="EmpBean_phoneNumbers_Pho8fj49g" data-source="jdbc/OracleDS">
   <primkey-mapping>
        <cmp-field-mapping name="empNo" persistence-name="empno" />
   </primkey-mapping>
   <cmp-field-mapping name="empName" persistence-name="ename" />
   <cmp-field-mapping name="salary" persistence-name="sal" />
   <cmp-field-mapping name="phoneNumbers">
     <collection-mapping table="EmpBean_phoneNumbers_Pho8fj49g">
       <primkey-mapping>
           <cmp-field-mapping name="empNo" persistence-name="EmpBean_empno" />
       </primkey-mapping>
       <value-mapping type="employee.PhoneLocal">
           <cmp-field-mapping>
             <entity-ref home="PhoneBean">
              <cmp-field-mapping name="phoneNumbers" 
                                       persistence-name="PhoneBean_autoid"/>
             </entity-ref>
            </cmp-field-mapping>
        </value-mapping>
      </collection-mapping>
    </cmp-field-mapping>
    ...
    </entity-deployment>

Figure 4-5 Demonstration of Explicit Mapping for a One-To-Many Relationship

Text description of ormap6.gif follows

Text description of the illustration ormap6.gif

Option for the One-To-Many Explicit Bidirectional Relationship

You can bypass an association table in the one-to-many bidirectional entity relationship. The "one" relationship has a primary key that points to the "many"; the "many" has a foreign key that points back. With both tables maintaining primary keys, and the "many" table maintaining a foreign key back to the "one" table, there is no need for an association table.

Figure 4-6 shows the department<->employee example, where each employee belongs to only one department and each department can contain multiple employees. The department table has a primary key. The employee table has a primary key to identify each employee and a foreign key to point back to the employee's department. If you want to find the department for a single employee, a simple SQL statement retrieves the department information from the foreign key. To find all employees in a department, the container performs a JOIN statement on both the department and employee tables and retrieves all employees with the designated department number.

Figure 4-6 One-To-Many Bidirectional Relationship Option

Text description of ormap2.gif follows

Text description of the illustration ormap2.gif

This is not the default behavior. To have this type of relationship, do one of the following:

To manipulate the <collection-mapping> element in the orion-ejb-jar.xml file, you modify the <entity-deployment> element for the "one" entity bean, which contains the Collection, as follows:

  1. Change the association table in the <collection-mapping> table attribute to be the "many" table. In this example, you would modify this attribute to be the EmpBean_empl_jar_employee table.

  2. Modify the column names in the persistence-name attribute for each entity bean in the <collection-mapping> table as follows:

    • The persistence-name of the <primkey-field> element should be the primary key of the source entity bean and the database column name of the foreign key in the target entity bean.

    • The <value-mapping> element provides a pointer to the target bean--the "many" bean. Thus, the <entity-ref> home attribute should be the target entity bean name. In the second <cmp-field-mapping> element, the name attribute contains the <cmr-field> defined in the "one" entity bean in the orion-ejb-jar.xml file. The persistence-name attribute defines the primary key column of the "one" entity bean table.

Figure 4-7 demonstrates how the department/employee one-to-many bidirectional example is mapped without the use of an association table.

Figure 4-7 Explicit Mapping for One-To-Many Bidirectional Relationship Example

Text description of ormap7.gif follows

Text description of the illustration ormap7.gif


Go to previous page Go to next page
Oracle
Copyright © 2002 Oracle Corporation.

All Rights Reserved.
Go To Core Documentation
Core
Go To Platform Documentation
Platform
Go To Table Of Contents
Contents
Go To Index
Index