CMP Relations Catalog
Resin 3.0

Features
Installation
Configuration
Web Applications
IOC/AOP
Resources
JSP
Quercus
Servlets and Filters
Databases
Admin (JMX)
CMP
EJB
Amber
EJB 3.0
Security
XML and XSLT
XTP
JMS
Performance
Protocols
Third-party
Troubleshooting/FAQ

User's Guide
Reference
Tutorials
Scrapbook

EJB Misconceptions
CMP Relations Catalog
CMP Performance
EJB Misconceptions
User's Guide
CMP Performance

  1. n-1 undirectional (Link)
  2. 1-1 Bidirectional (Pair)
  3. 1-n Bidirectional (Container)
  4. 1-n uni-directional (Container)
  5. n-m bi-directional
  6. Identifying: 1-1 Bidirectional (Pair)
  7. Identifying: n-1 Container (compound key)

This section lists several of the common relation patterns along with their configuration.

n-1 undirectional (Link)

The easiest relation is the one-way link. In this example, each student has a favorite Quidditch team (a wizard sport.) The link is unidirectional because the teams don't keep track of all their student fans.

n-1 SQL schema
CREATE TABLE students (
  id VARCHAR(250) NOT NULL,

  quidditch_team VARCHAR(250),

  PRIMARY KEY(id)
);

CREATE TABLE quidditch_team (
  id VARCHAR(250) NOT NULL,

  PRIMARY KEY(id)
);

Student EJBLocalObject interface
public interface Student extends EJBLocalObject {
  String getId();

  QuidditchTeam getQuidditchTeam();

  void setQuidditchTeam(QuidditchTeam team);
}

QuidditchTeam EJBLocalObject interface
public interface QuidditchTeam extends EJBLocalObject {
  String getId();
}

n-1 EJB deployment descriptor
<relationships>
  <ejb-relation>
    <ejb-relationship-role>
      <relationship-role-source>
        <ejb-name>students</ejb-name>
      </relationship-role-source>

      <cmr-field>
        <cmr-field-name>quidditchTeam</cmr-field-name>
      </cmr-field>

      <multiplicity>Many</multiplicity>
    </ejb-relationship-role>

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

      <multiplicity>One</multiplicity>
    </ejb-relationship-role>
  </ejb-relation>
</relationships>

n-1 relation (short form)
<ejb-relation>
  <source-ejb>students</source-ejb>
  <source-field>quidditchTeam</source-field>
  <source-multiplicity>Many</source-multiplicity>

  <target-ejb>quidditch_teams</target-ejb>
  <target-multiplicity>One</target-multiplicity>
</ejb-relation>

1-1 Bidirectional (Pair)

1-1 SQL schema
CREATE TABLE courses (
  id VARCHAR(250) NOT NULL,

  teacher VARCHAR(250),

  PRIMARY KEY(id)
);

CREATE TABLE teachers (
  id VARCHAR(250) NOT NULL,

  PRIMARY KEY(id)
);

Course EJBLocalObject interface
public interface Course extends EJBLocalObject {
  String getId();

  Teacher getTeacher();
  void setTeacher(Teacher teacher);
}

Teacher EJBLocalObject interface
public interface Teacher extends EJBLocalObject {
  String getId();

  Course getCourse();
  void setCourse(Course course);
}

1-1 deployment descriptor
<relationships>
  <ejb-relation>
    <ejb-relationship-role>
      <relationship-role-source>
        <ejb-name>teachers</ejb-name>
      </relationship-role-source>

      <cmr-field>
        <cmr-field-name>course</cmr-field-name>
      </cmr-field>

      <multiplicity>One</multiplicity>
    </ejb-relationship-role>

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

      <cmr-field>
        <cmr-field-name>teacher</cmr-field-name>
      </cmr-field>

      <multiplicity>One</multiplicity>
    </ejb-relationship-role>
  </ejb-relation>
</relationships>

1-1 relation (short form)
<ejb-relation>
  <source-ejb>teachers</source-ejb>
  <source-field>course</source-field>
  <source-multiplicity>One</source-multiplicity>

  <target-ejb>courses</target-ejb>
  <target-field>teacher</target-field>
  <target-multiplicity>One</target-multiplicity>
</ejb-relation>

1-n Bidirectional (Container)

The container relation is possibly the most common relation. It's more fully described in the one to many example.

In the example, students belong to a dorm. The Student object can return the Dorm, and the Dorm object can return all the Students.

In the database, the student's entry manages the link; it points to the dorm. Resin-CMP generates the Dorm's student list with a database query.

1-n SQL schema
CREATE TABLE dorms (
  id VARCHAR(250) NOT NULL,

  PRIMARY KEY(id)
);

CREATE TABLE students (
  id VARCHAR(250) NOT NULL,

  dorm VARCHAR(250),

  PRIMARY KEY(id)
);

Dorm EJBLocalObject interface
public interface Dorm extends EJBLocalObject {
  String getId();

  Collection getStudents();
}

Student EJBLocalObject interface
public interface Student extends EJBLocalObject {
  String getId();

  Dorm getDorm();
  void setDorm(Dorm dorm);
}

1-n deployment descriptor
<relationships>
  <ejb-relation>
    <ejb-relationship-role>
      <relationship-role-source>
        <ejb-name>dorms</ejb-name>
      </relationship-role-source>

      <cmr-field>
        <cmr-field-name>students</cmr-field-name>
      </cmr-field>

      <multiplicity>One</multiplicity>
    </ejb-relationship-role>

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

      <cmr-field>
        <cmr-field-name>dorm</cmr-field-name>
      </cmr-field>

      <multiplicity>Many</multiplicity>
    </ejb-relationship-role>
  </ejb-relation>
</relationships>

1-n relation (short form)
<ejb-relation>
  <source-ejb>dorms</source-ejb>
  <source-field>students</source-field>
  <source-multiplicity>One</source-multiplicity>

  <target-ejb>students</target-ejb>
  <target-field>dorm</target-field>
  <target-multiplicity>Many</target-multiplicity>
</ejb-relation>

1-n uni-directional (Container)

1-n database schema
CREATE TABLE dorms (
  id VARCHAR(250) NOT NULL,

  PRIMARY KEY(id)
);

CREATE TABLE students (
  id VARCHAR(250) NOT NULL,

  PRIMARY KEY(id)
);

CREATE TABLE student_dorm_map (
  dorm VARCHAR(250) NOT NULL,
  student VARCHAR(250) NOT NULL,
);

Dorm EJBLocalObject interface
public interface Dorm extends EJBLocalObject {
  String getId();

  Collection getStudents();
}

Student EJBLocalObject interface
public interface Student extends EJBLocalObject {
  String getId();
}

1-n deployment descriptor
<relationships>
  <ejb-relation>
    <ejb-relationship-name>student_dorm_map</ejb-relationship-name>

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

      <cmr-field>
        <cmr-field-name>students</cmr-field-name>
      </cmr-field>

      <multiplicity>One</multiplicity>
    </ejb-relationship-role>

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

      <multiplicity>Many</multiplicity>
    </ejb-relationship-role>
  </ejb-relation>
</relationships>

1-n relation (short form)
<ejb-relation>
  <ejb-relationship-name>student_dorm_map</ejb-relationship-name>

  <source-ejb>dorms</source-ejb>
  <source-field>students</source-field>
  <source-multiplicity>One</source-multiplicity>

  <target-ejb>students</target-ejb>
  <target-multiplicity>Many</target-multiplicity>
</ejb-relation>

n-m bi-directional

CREATE TABLE courses (
  id VARCHAR(250) NOT NULL,

  PRIMARY KEY(id)
);

CREATE TABLE students (
  id VARCHAR(250) NOT NULL,

  PRIMARY KEY(id)
);

CREATE TABLE student_course_map (
  course VARCHAR(250) NOT NULL,
  student VARCHAR(250) NOT NULL,
);

public interface Course extends EJBLocalObject {
  String getId();

  Collection getStudents();
}

public interface Student extends EJBLocalObject {
  String getId();

  Collection getCourses();
}

ejb-relation (long form)
<ejb-relation>
  <ejb-relationship-name>student_course_map</ejb-relationship-name>

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

    <cmr-field>
      <cmr-field-name>students</cmr-field-name>
    </cmr-field>

    <multiplicity>Many</multiplicity>
  </ejb-relationship-role>

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

    <cmr-field>
      <cmr-field-name>courses</cmr-field-name>
    </cmr-field>

    <multiplicity>Many</multiplicity>
  </ejb-relationship-role>
</ejb-relation>

ejb-relation (short form)
<ejb-relation>
  <ejb-relationship-name>student_course_map</ejb-relationship-name>

  <source-ejb>courses</source-ejb>
  <source-field>students</source-field>
  <source-multiplicity>Many</source-multiplicity>

  <target-ejb>students</target-ejb>
  <target-field>courses</target-field>
  <target-multiplicity>Many</target-multiplicity>
</ejb-relation>

Identifying: 1-1 Bidirectional (Pair)

A bean with an identifying relation has a primary key which is a reference to another bean. In this case, a course bean may have a unique room bean.

CREATE TABLE courses (
  id VARCHAR(250) NOT NULL,

  PRIMARY KEY(id)
);

CREATE TABLE course_rooms (
  course VARCHAR(250) NOT NULL REFERENCES courses(id),

  name VARCHAR(250),

  PRIMARY KEY(course)
);

Course local interface
public interface Course extends EJBLocalObject {
  String getId();

  Room getRoom();
}

Room local interface
public interface Room extends EJBLocalObject {
  Course getCourse();

  String getName();
  void setName(String name);
}

Room entity definition
<entity>
  <ejb-name>room</ejb-name>
  <local-home>qa.RoomLocalHome</local-home>
  <local>qa.Room</local>
  <ejb-class>qa.RoomBean</ejb-class>
  <prim-key-class>qa.Course</prim-key-class>
  <primkey-field>course</primkey-field>

  <persistence-type>Container</persistence-type>
  <reentrant>True</reentrant>

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

  <sql-table>course_rooms</sql-table>
</entity>

ejb-relation (long form)
<ejb-relation>
  <ejb-relationship-role>
    <relationship-role-source>
      <ejb-name>rooms</ejb-name>
    </relationship-role-source>

    <cmr-field>
      <cmr-field-name>course</cmr-field-name>
    </cmr-field>

    <multiplicity>One</multiplicity>
  </ejb-relationship-role>

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

    <cmr-field>
      <cmr-field-name>room</cmr-field-name>
    </cmr-field>

    <multiplicity>One</multiplicity>
  </ejb-relationship-role>
</ejb-relation>

ejb-relation (short form)
<ejb-relation>
  <source-ejb>rooms</source-ejb>
  <source-field>course</source-field>
  <source-multiplicity>One</source-multiplicity>

  <target-ejb>courses</target-ejb>
  <target-field>room</target-field>
  <target-multiplicity>One</target-multiplicity>
</ejb-relation>

Identifying: n-1 Container (compound key)

For many container relations, the item has a compound primary key pointing to the container and including an additional identifier. The item bean will have a compound key class where one of the keys points to the container.

CREATE TABLE students (
  id INTEGER NOT NULL,

  name VARCHAR(250),

  PRIMARY KEY(id)
);

CREATE TABLE demerits (
  student INTEGER NOT NULL REFERENCES students(id),
  id INTEGER NOT NULL,

  points INTEGER,
  reason VARCHAR(250),

  PRIMARY KEY(student, id)
);

Student local interface
public interface Student extends EJBLocalObject {
  int getId();

  String getName();

  Collection getDemerits();
}

Demerit local interface
public interface Demerit extends EJBLocalObject {
  Student getStudent();
  int getId();

  int getPoints();
  String getReason();
}

DemeritKey
public class DemeritKey {
  public int student;
  public int id;
}

Demerit entity definition
<entity>
  <ejb-name>demerit</ejb-name>
  <local-home>qa.DemeritLocalHome</local-home>
  <local>qa.Demerit</local>
  <ejb-class>qa.DemeritBean</ejb-class>
  <prim-key-class>qa.DemeritKey</prim-key-class>

  <persistence-type>Container</persistence-type>
  <reentrant>True</reentrant>

  <cmp-field><field-name>points</field-name></cmp-field>
  <cmp-field><field-name>reason</field-name></cmp-field>

  <sql-table>demerits</sql-table>
</entity>

ejb-relation (long form)
<ejb-relation>
  <ejb-relationship-role>
    <relationship-role-source>
      <ejb-name>demerits</ejb-name>
    </relationship-role-source>

    <cmr-field>
      <cmr-field-name>student</cmr-field-name>
    </cmr-field>

    <multiplicity>Many</multiplicity>
  </ejb-relationship-role>

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

    <cmr-field>
      <cmr-field-name>demerits</cmr-field-name>
    </cmr-field>

    <multiplicity>One</multiplicity>
  </ejb-relationship-role>
</ejb-relation>

ejb-relation (short form)
<ejb-relation>
  <source-ejb>demerits</source-ejb>
  <source-field>student</source-field>
  <source-multiplicity>Many</source-multiplicity>

  <target-ejb>students</target-ejb>
  <target-field>demerits</target-field>
  <target-multiplicity>One</target-multiplicity>
</ejb-relation>


EJB Misconceptions
User's Guide
CMP Performance
Copyright © 1998-2006 Caucho Technology, Inc. All rights reserved.
Resin® is a registered trademark, and HardCoretm and Quercustm are trademarks of Caucho Technology, Inc.