Skip Headers

Oracle® Application Server Containers for J2EE Enterprise JavaBeans Developer's Guide
10g Release 2 (10.1.2)
Part No. B15505-01
  Go To Documentation Library
Home
Go To Product List
Solution Area
Go To Table Of Contents
Contents
Go To Index
Index

Previous
Previous
Next
Next
 

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:

  • one-to-one

  • one-to-many or many-to-one (dependent on the direction)

  • many-to-many

In addition, each relationship can unidirectional or 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.

You can use a unidirectional relationship when you want to reuse the target from multiple entities. For example, both a husband and a wife may work for the same company. Both of their employee records could point to the same home phone number in a unidirectional relationship. You could not have this situation in a bidirectional relationship.

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.

Requirements in Defining Relationships

Here are the restrictions imposed on defining your relationships:

  • You can define relationships only between CMP 2.0 entity beans.

  • You must declare both EJBs in the relationship within the same deployment descriptor.

  • Each relationship can use only the local interface of the target EJB.

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. Set the relationships in the bean implementation. The primary key must always be set in the ejbCreate method; the foreign key can be set anytime after the ejbCreate method, but not within it.

  3. 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.

  4. If you want cascade delete, then declare 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 slave side of the relationship, so that when the master entity is deleted, all of the slave entities related to it are subsequently deleted. For example, when an employee has multiple phone numbers, the cascade delete is defined on the phone numbers side. Then, when the employee is deleted, all of the related phone numbers are also deleted.

The following sections provides an example of how to implement each of these requirements:

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 6-1 Definition of Abstract Accessor Methods for the Employee Example

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

public Integer getEmpNo();
public void setEmpNo(Integer empNo);
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 6-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);

Set the Relationships in the Bean Implementation

Once you have defined the get/set relationship methods, use them in the bean implementation to set up the relationships. All primary key relationships must be set within the ejbCreate method, as shown in "Implement the Entity Bean Class". If you use a foreign key, as described in "Using a Foreign Key in a Composite Primary Key", you can set the foreign key as early as the ejbPostCreate method.

When you set the primary key in the ejbCreate, the set methods populate the CMP fields that you define in the deployment descriptor. At the end of the ejbCreate method, these fields are written out to the appropriate database row.

The employee has a primary key of the employee number. The following sets the primary key for the department:

public Integer ejbCreate(Integer empNo) throws CreateException
{
    setEmpNo(empNo);
    return empNo;
}

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>

Note:

An object-relationship entity bean example is available on OTN from the OC4J sample code page at http://www.oracle.com/technology/tech/java/oc4j/demos/ on the OTN Web site.

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

Table 6-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 in the ejb-jar.xml file.
<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,

  • One-to-one: For one employee to have a relationship with one address, the employee bean is declared with a <multiplicity> of one, and the address bean is declared with a <multiplicity> of one.

  • One-to-many, many-to-one: For one department to have a relationship with multiple employees, the department bean is declared with a <multiplicity> of one, and the employee bean is declared with a <multiplicity> of many. For many employees to belong to a department, you define the same <multiplicity>.

  • Many-to-many: For each employee to have a relationship with multiple projects and each project to have multiple employees working on it, the employee bean is declared with a <multiplicity> of many, and the project is declared with a <multiplicity> of many.

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> element. If the relationship is unidirectional, then only one entity within the relationship contains a reference to a target. In this case, the <cmr-field> element is declared in the source entity and contains the target bean reference. If the relationship is bidirectional, both entities should declare a reference to each other's bean within a <cmr-field> element.

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

  • Unidirectional: Define the <cmr-field> element within the employee bean section that references the address bean. Do not define a <cmr-field> element in the address bean section of the relationship.

  • Bidirectional: Define a <cmr-field> element in the employee bean section that references the address bean. In addition, define a <cmr-field> element in the address bean section that references the employee bean.

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

Example 6-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.

The ejb-jar.xml file is configured for this example, as follows:

<enterprise-beans>
  <entity>
    ...
    <ejb-name>EmpBean</ejb-name>
    <local-home>employee.EmpHome</local-home>
    <local>employee.Emp</local>
    <ejb-class>employee.EmpBean</ejb-class>
    ...
  </entity>
  <entity>
    ...
    <ejb-name>AddressBean</ejb-name> 
    <local-home>employee.AddressHome</local-home>
    <local>employee.Address</local>
    <ejb-class>employee.AddressBean</ejb-class>
    ...
  </entity>
</enterprise-beans>
...
<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>
            <relationship-role-source><ejb-name>AddressBean</ejb-name>
            </relationship-role-source>
         </ejb-relationship-role>
      </ejb-relation>
</relationships>

The ejb-jar.xml file has defined the following:

  • Configure each <entity> element within the <enterprise-beans> section for each of the entity beans involved in the relationship. For this example, these include an <entity> element for the employee with an <ejb-name> of EmpBean and an <entity> element for the address with an <ejb-name> of AddressBean.

  • Configure the <ejb-relationship> element within the <relationships> section for the one-to-one relationship. For this example, it defines the following:

    • An <ejb-relationship-role> element for the employee bean that defines its cardinality as "one" in its <multiplicity> element. The <relationship-role-source> element defines the <ejb-name> as EmpBean, which is the same name in the <entity> element.

    • An <ejb-relationship-role> element for the address bean that defines its cardinality as "one" in its <multiplicity> element. The <relationship-role-source> element defines the <ejb-name> as AddressBean, which is the same name in the <entity> element.

  • Configure a <cmr-field> element in the EmpBean relationship that points to the AddressBean. The <cmr-field> element defines address as the AddressBean reference. This element name matches the get and set method names, which are named getAddress and setAddress. These methods identify the local interface of the address entity bean as the data type that is returned from the get method and passed in on the set method.


    Note:

    An object-relationship entity bean example is available on OTN from the OC4J sample code page at http://www.oracle.com/technology/tech/java/oc4j/demos/ on the OTN Web site.

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? If you specify cascade delete, the deletion of a master entity bean automatically deletes all of its slave relationship entity beans. You specify the cascade delete option in the slave relationship definition, which is the object that is deleted automatically.

For example, an employee has a relationship with an address object. The address 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.

Example 6-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>