<document>
  <header>
    <product>resin-ee</product>
    <title>Many-to-Many CMP</title>
        <description>
          <p>Illustrates using many-to-many relations of EJB 3.0.</p>
        </description>
    <type>tutorial</type>
    <tutorial-startpage>many2many</tutorial-startpage>
  </header>

  <body>
    <summary/>

<s1 title="Files in this tutorial">
<deftable>
<tr>
  <th>File</th>
  <th>Description</th>
</tr>
<tr><td><viewfile-link file="WEB-INF/resin-web.xml"/>
    </td><td>resin-web.xml configuration
</td></tr><tr><td><viewfile-link file="WEB-INF/classes/META-INF/persistence.xml"/>
    </td><td>persistence.xml configuration
</td></tr><tr><td><viewfile-link file="WEB-INF/classes/example/Student.java"/>
    </td><td>The student bean
</td></tr><tr><td><viewfile-link file="WEB-INF/classes/example/Course.java"/>
    </td><td>The course bean
</td></tr><tr><td><viewfile-link file="WEB-INF/classes/example/Grade.java"/>
    </td><td>The grade bean
</td></tr><tr><td><viewfile-link file="WEB-INF/classes/example/ManyToManyServlet.java"/>
    </td><td>The course servlet
</td></tr></deftable>
</s1>

<s1 title="Entity Beans">

<p>The many-to-many relation connects two tables with an association table.
In the example, each Student takes several Courses.  A grade_map table
connects the two.  Using the many-to-many relation, the application
can return the student's courses or the students in a course.</p>

<example title="SQL Schema">
CREATE TABLE Course (
  course_id BIGINT PRIMARY KEY,

  name VARCHAR(255)
)

CREATE TABLE Student (
  student_id BIGINT PRIMARY KEY,

  name VARCHAR(255)
)

CREATE TABLE grade_map (
  id BIGINT PRIMARY KEY auto_increment,

  student_id BIGINT REFERENCES Student(student_id),
  course_id BIGINT REFERENCES Course(course_id)
)
</example>

<p>The Course has an @Id and a data column for the name.</p>

<example title="Course.java">
<a href="doc|amber-table.xtp#@Entity">@Entity</a>
public class Course {
  <a href="doc|amber-table.xtp#@Id">@Id</a>
  <a href="doc|amber-table.xtp#@Column">@Column</a>(name="course_id")
  public long getId()

  <a href="doc|amber-table.xtp#@Basic">@Basic</a>
  public String getName()
}
</example>

<p>The Student includes the many-to-many relation in its definition.</p>

<example title="Student.java">
<a href="doc|amber-table.xtp#@Entity">@Entity</a>
public class Student {
  <a href="doc|amber-table.xtp#@Id">@Id</a>
  <a href="doc|amber-table.xtp#@Column">@Column</a>(name="student_id")
  public long getId()

  <a href="doc|amber-table.xtp#@Basic">@Basic</a>
  public String getName()

  <a href="doc|amber-table.xtp#@ManyToMany">@ManyToMany(targetEntity="Course")</a>
  <a href="doc|amber-table.xtp#@JoinTable">@JoinTable</a>(
      table=<a href="doc|amber-table.xtp#@Table">@Table</a>(name="student_course_map"),
      joinColumns=<a href="doc|amber-table.xtp#@JoinColumn">@JoinColumn</a>(name="student_id")",
      inverseJoinColumns=<a href="doc|amber-table.xtp#@JoinColumn">@JoinColumn</a>(name="course_id")")
  public Collection getCourses()
}
</example>
</s1>

<s1 title="@ManyToMany">

<p>The <a href="doc|amber-table.xtp#@ManyToMany">@ManyToMany</a>
annotation marks a collection-valued field as a many-to-many relation.
The <code>targetEntity</code> value specifies the target of the
relation.
</p>

<p>Since the many-to-many relation is a three-table relation, it needs
to specify the association table as well as the columns.</p>

</s1>

<s1 title="Client">

<example title="ManyToManyServlet.java">
  private void doService(PrintWriter out)
    throws java.io.IOException
  {
    PrintWriter out = res.getWriter();

    res.setContentType("text/html");

    Query allStudent = _entityManager.createQuery("SELECT o FROM Student o");
    
    List students = allStudent.listResults();

    for (int i = 0; i &lt; students.size(); i++) {
      Student student = (Student) students.get(i);

      out.println("&lt;h3&gt;" + student.getName() + "&lt;/h3&gt;");

      Collection courses = student.getCourses();

      out.println("&lt;ul&gt;");
      Iterator iter = courses.iterator();
      while (iter.hasNext()) {
	Course course = (Course) iter.next();

	out.println("&lt;li&gt;" + course.getName());
      }
      out.println("&lt;/ul&gt;");
    }
  }
}
</example>

</s1>
  </body>
</document>