<document>
  <header>
    <product>resin-ee</product>
    <title>Links: The @ManyToOne Relation</title>
        <description>

<p>The Many-to-One link is the foundation of persistent relations.
It links a source table to a destination with a database REFERENCES column.
Many-to-One adds two capabilities: SQL extensions for links and direct lookup of target beans through field references.</p>

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

  <body>
    <summary/>

<section title="Files in this tutorial">
<deftable>
<tr><td><viewfile-link file="WEB-INF/resin-web.xml"/>
    <td>resin-web.xml configuration
<tr><td><viewfile-link file="WEB-INF/classes/META-INF/persistence.xml"/>
    <td>persistence.xml configuration
<tr><td><viewfile-link file="WEB-INF/classes/example/Student.java"/>
    <td>The student bean
<tr><td><viewfile-link file="WEB-INF/classes/example/House.java"/>
    <td>The house bean
<tr><td><viewfile-link file="WEB-INF/classes/example/ManyToOneServlet.java"/>
    <td>The test servlet
</deftable>
</section>

<section title="Model: Database and Annotated Classes">

<section title="Database Schema">

<p>A many-to-one relation links one table to another.  In this example,
each student entry links to the student's house.  The database schema
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>

</section>

<p>The House bean has two fields, <var>id</var> and <var>name</var>,
to model the house columns.  House annotates <code>getId</code> with <code>@Id</code> to mark it as a primary key.  It annotates <code>getName</code>
with <code>@Basic</code> to mark it as a data column.</p>

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

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

<p>The Student bean adds a many-to-one field, <var>house</var> to the
<var>id</var> and <var>name</var> columns.  It marks the <code>getHouse</code>
getter with <code>@ManyToOne</code> to mark it as a many-to-one column.</p>

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

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

  <a href="amber|amber-table.xtp#@ManyToOne">@ManyToOne</a>
  <a href="amber|amber-table.xtp#@JoinColumn">@JoinColumn</a>(name="house")
  public House getHouse()
}
</example>

<section title="@ManyToOne">

<p><a href="amber|amber-table.xtp#@ManyToOne">@ManyToOne</a> marks the
field as a many-to-one field.  The <code>@ManyToOne</code> annotation
can also specify the target bean.  By default, the field's type determines
the target bean.</p>

</section>

<section title="@JoinColumn">

<p><a href="amber|amber-table.xtp#@JoinColumn">@JoinColumn</a> specifies
the SQL column name and the target column for a many-to-one field.</p>

<p>The default column name is the name of the many-to-one field.</p>

<p>The default target column is the primary key of the target table.</p>

</section>

</section>

<section title="Client Servlet">

<p>The many-to-one relation provides two capabilities to the client:</p>
<ol>
<li>Extended SQL relation capabilities
<li>A direct lookup to a persistent bean through the field.
</ol>

<section title="Query Extensions">

<p>The first relation capability extends SQL with relation paths
using the '.' operator like Java's field reference.
If <code>s</code> is a student,
then <code>s.house</code> is the student's house
and <code>s.house.name</code> is the name of
the student's house.  Resin translates the extended SQL to plain
SQL automatically.</p>

<p>The following example uses the extended SQL to return all students
in a given house.</p>

<example>
private void doService(PrintWriter out)
  throws java.io.IOException
{
  String sql = "SELECT s FROM Student s WHERE s.house.name=?1";
    
  Query houseStudents = _entityManager.createQuery(sql);
  houseStudents.setParameter(1, "Gryffindor");

  students = houseStudent.getResultList();

  out.println("&lt;h3>Gryffindor Students&lt;/h3>");

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

    out.println(student.getName() + "&lt;br>");
  }
}
</example>

</section>

<section title="Java References">

<p>The second relation capability returns a live, persistent bean through
the <code>getHouse()</code> method.  Amber will perform any necessary
database lookup.</p>

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

<example title="ManyToOneServlet.java">
private void doService(PrintWriter out)
  throws java.io.IOException
{
  Query allStudent = _entityManager.createQuery("SELECT o FROM Student o");
    
  List students = allStudent.getResultList();

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

    out.println(student.getName() + " lives in " +
                student.getHouse().getName() + "&lt;br>");
  }
}
</example>

</section>

</section>

  </body>
</document>
