<document>
  <header>
    <product>resin-ee</product>
    <title>Collections: The @OneToMany Relation</title>
        <description>
<p>The @OneToMany relation adds collection extensions to the query language
and provides a Java Collection containing the children.  @OneToMany
represents a collection of children belonging to a parent,
like students in Gryffindor house at Hogwarts school.</p>

<p>
The <a href="examples|amber-many2one/index.xtp">Many-To-One tutorial</a>
illustrated that a many-to-one relation links one source entity to another
target entity.  A one-to-many relation links the target entity back to the
source entity.
</p>

<p>
In this example, 
each House has many Students, 
each Student has one House.
House has a one-to-many relationship with Student,
Student has a many-to-one relationship with House
</p>

        </description>
    <type>tutorial</type>
    <tutorial-startpage>one2many</tutorial-startpage>
  </header>

  <body>
    <summary/>

<s1 title="Files in this tutorial">
<deftable>
<tr><td><viewfile-link file="WEB-INF/resin-web.xml"/>
    </td><td>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/House.java"/>
    </td><td>The house bean
</td></tr><tr><td><viewfile-link file="WEB-INF/classes/example/OneToManyServlet.java"/>
    </td><td>The test servlet
</td></tr></deftable>
</s1>

<s1 title="Data Model: Object and Database Models">

<s2 title="Database Schema">

<p>
The database schema is unchanged from the
<a href="../amber-many2one/index.xtp">Many-To-One tutorial</a>,
and might look like:</p>

<example title="SQL">
CREATE TABLE house (
  id BIGINT PRIMARY KEY auto_increment,

  name VARCHAR(250),
)

CREATE TABLE student (
  id BIGINT PRIMARY KEY auto_increment,

  name VARCHAR(250),

  house BIGINT REFERENCES house(id)
)
</example>
</s2>

<s2 title="@OneToMany - the relation's &quot;inverse&quot; side ">
<p>The <var>House</var> bean has a students field that returns the students that belong to the house.  House annotates <code>getStudents</code> with 
<code>@OneToMany</code> to describe the relationship.  The <code>@JoinColumn</code> is used to specify the <i>foreign key</i>, the field in <var>Student</var> 
that is the <code>@ManyToOne</code> link.
</p>

<example title="House.java">
  @OneToMany(mappedBy="house")
  private Set&lt;Student&gt; _students;
</example>
</s2>

<s2 title="@ManyToOne - the relation's &quot;owning&quot; side">
<p>
A @OneToMany always requires a corresponding @ManyToOne on the target entity.
The Student has a house field annotated a <code>@ManyToOne</code>,
unchanged from the 
<a href="../amber-many2one/index.xtp">Many-To-One tutorial</a>.
</p>

<example title="Student.java">
  @ManyToOne
  @JoinColumn(name="house")
  private House _house;
</example>

</s2>
</s1>
<!--
<section title="@FetchType">
<p>
Often a <code>@OneToMany</code> relationship should be marked as <var/lazy/>.
This indicates that the target entities should not be retrieved from the
database until the <code>@OneToMany</code> field is used.
</p>

<p>
The <code>@OneToMany</code> annotation for the students field indicates a
FetchType of <code/LAZY/>.  A House can potentially have many Students, and in
use the students may not be needed by the code using the House bean.  For
example, if the goal is to display a summary list only Houses, the associated
Student's will not be needed and it would be inefficient to fetch them each
time.
</p>

<example title="House.java">
  @OneToMany(targetEntity=Student.class, mappedBy="house")
  public Set&lt;Student&gt; getStudents()
</example>

</section>
-->
<s1 title="java.util.Collection: Using House.getStudents()">

<p>
The one-to-many relation provides a House the ability to get all of its
Students.  Resin will perform any necessary
database lookup.
</p>

<p>The example queries all houses and prints their
names and all of their students.</p>

<example title="Using House.getStudents()">
private void doService(PrintWriter out)
  throws java.io.IOException
{
  public void service(HttpServletRequest req, HttpServletResponse res)
    throws java.io.IOException, ServletException
  {
    PrintWriter out = res.getWriter();

    res.setContentType("text/html");

    String sql = "SELECT h FROM House h";
    
    Query allHouse = _entityManager.createQuery("SELECT o FROM House o");

    List houses = allHouse.getResultList();

    for (int i = 0; i &lt; houses.size(); i++) {
      House house = (House) houses.get(i);

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

      for ( Student student : house.getStudents() ) {
        out.println( student.getName() + "&lt;br&gt;" );
      }
    }
  }
}
</example>

</s1>

<s1 title="Query extensions">

<s2 title="Result Collections: SELECT h.students">

<example title="h.students">
SELECT h.students FROM House h WHERE h.name='Gryffindor'
</example>

</s2>

<s2 title="Joins: FROM House h, IN(h.students) s">

<example title="IN">
SELECT s FROM House h, IN(h.students) s WHERE h.name='Gryffindor'
</example>

</s2>

<s2 title="Membership: s MEMBER OF h.students">

<example title="MEMBER OF">
SELECT s FROM Student s, House h WHERE s MEMBER OF h.students
</example>

</s2>

<s2 title="Empty: h.students IS EMPTY">

<example title="IS EMPTY">
SELECT h FROM House h WHERE h.students IS EMPTY
</example>

</s2>

</s1>

  </body>
</document>
