<document>
  <header>
    <product>resin-ee</product>
    <title>CMP Inheritance</title>
        <description>
          <p>Amber supports database-backed inheritance, allowing
for persistent-backed polymorphism and more sophisticated
object-oriented modelling.</p>

          <p>The example uses a single table to represent both Student
and Prefect values.  The "type" column serves as a discriminator to
select the proper type.</p>
        </description>
    <type>tutorial</type>
    <tutorial-startpage>query</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>META-INF/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/Prefect.java"/>
    </td><td>The prefect bean
</td></tr><tr><td><viewfile-link file="WEB-INF/classes/example/QueryServlet.java"/>
    </td><td>The course servlet
</td></tr></deftable>
</s1>

<s1 title="Database Schema">

<example title="student.sql">
CREATE TABLE amber_inherit_student (
  id BIGINT PRIMARY KEY auto_increment,

  type VARCHAR(10),

  name VARCHAR(250)
);

INSERT INTO amber_inherit_student VALUES(1, 'student', 'Harry Potter')
INSERT INTO amber_inherit_student VALUES(2, 'prefect', 'Ron Weasley')
INSERT INTO amber_inherit_student VALUES(1, 'prefect', 'Hermione Granger')
</example>

</s1>

<s1 title="Bean Implementation">

<p>The example has two beans to illustrate inheritance.  The Student
bean is the base class and represents all students.  Some students are
also prefects.  The prefect students are represented by a Prefect
class.</p>

<p>In the database, the <var>type</var> column distinguishes between
Students and Prefects.  A <var>type</var> of "student" creates a
Student bean and a <var>type</var> of "prefect" creates a Prefect bean.</p>

<example title="Student.java">
package example;

<a href="doc|amber-table.xtp#@Entity">@javax.ejb.Entity</a>(access=FIELD)
<a href="doc|amber-table.xtp#@Table">@javax.ejb.Table</a>(name="ejb3_inherit_student")
<a href="doc|amber-table.xtp#@Inheritance">@javax.ejb.Inheritance</a>(discriminatorValue="student")
<a href="doc|amber-table.xtp#@DiscriminatorColumn">@javax.ejb.DiscriminatorColumn</a>(name="type")
public class Student {
  <a href="doc|amber-table.xtp#@Id">@javax.ejb.Id</a>(generator=AUTO)
  <a href="doc|amber-table.xtp#@Column">@javax.ejb.Column</a>(name="id")
  private long _id;

  <a href="doc|amber-table.xtp#@Basic">@javax.ejb.Basic</a>
  <a href="doc|amber-table.xtp#@Column">@javax.ejb.Column</a>(name="name")
  private String _name;

  public Student()
  {
  }

  public Student(String name)
  {
    _name = name;
  }

  public String getName()
  {
    return _name;
  }

  public String toString()
  {
    return "Student[_name]";
  }
}
</example>

<s2 title="@Inheritance">

<p>The <a href="doc|amber-table.xtp#@Inheritance">@Inheritance</a>
annotation marks the entity bean as supporting inheritance.</p>

<p>Amber supports two inheritance types: SINGLE_TABLE and JOINED.
SINGLE_TABLE uses a single table for all classes and JOINED adds
additional tables for child classes.  Both types use a discriminator
column in the base table to mark the Java type of the database entry.
SINGLE_TABLE is the default.</p>

<p>This example uses the default SINGLE_TABLE since there's no
additional information for the Prefect.  The example only uses
inheritance to illustrate the database polymorphism.</p>

<p>The values in the discriminator column determine the Java class.
Each entity will specify its discriminator value in the 
discriminatorValue annotation.  In the example, the Student
class has a "student" value
and the Prefect class has a "prefect" value.</p>

</s2>

<s2 title="@DiscriminatorColumn">

<p>Both SINGLE_TABLE and JOINED use a discriminator column to
distinguish the classes.  The <a href="doc|amber-table.xtp#@DiscriminatorColumn">@DiscriminatorColumn</a>
annotation specifies the column name.  In this example, the column is
"type".  The default discriminator column is "TYPE".</p>

</s2>

<example title="Prefect.java">
package example;

import static javax.ejb.AccessType.FIELD;

<a href="doc|amber-table.xtp#@Entity">@javax.ejb.Entity</a>(access=FIELD)
<a href="doc|amber-table.xtp#@Inheritance">@javax.ejb.Inheritance</a>(discriminatorValue="prefect")
public class Prefect {
  public Prefect()
  {
  }

  public Prefect(String name)
  {
    super(name);
  }

  public String toString()
  {
    return "Prefect[" + getName() + "]";
  }
}
</example>

<p>In this example, the Prefect class has no additional columns, so
it only specifies the @Entity and @Inheritance values.  When Resin
loads the objects from the database, it will instantiate the proper
type.
</p>

</s1>

<s1 title="Client Servlet">

<p>The client code using inheritance is no different from normal
queries.  The Query will perform any necessary database joins to
return the proper Java class.   In this case, prefects will
return Prefect objects and students will return Student objects.</p>

<example title="QueryServlet.java">
public void service(PrintWriter out)
  throws IOException
{
  out.println("&lt;h3&gt;Students&lt;/h3&gt;");

  Query query = _manager.createQuery("SELECT o FROM Student o");
    
    for (Object student : query.listResults()) {
      out.println("student: " + student() + "&lt;br&gt;");
    }
  }
}
</example>
<results>
&lt;h3&gt;Students&lt;/h3&gt;
Student[Harry Potter]
Prefect[Hermione Granger]
Prefect[Ron Weasley]
</results>

</s1>

  </body>
</document>