CMP Inheritance
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

Amber
Lifecycle
@Table
Tutorials

CMP Field
CMP Basic
CMP Create
Transactions
CMP Query
CMP Many-to-One
CMP One-to-Many
CMP Many-to-Many
CMP Inherit
Sessions
CMP Many-to-Many
Tutorials
Sessions

Find this tutorial in: /usr/local/resin/webapps/resin-doc/amber/tutorial/cmp-inherit
Try the Tutorial

Amber supports database-backed inheritance, allowing for persistent-backed polymorphism and more sophisticated object-oriented modelling.

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.

  1. Files in this tutorial
  2. Database Schema
  3. Bean Implementation
    1. @Inheritance
    2. @DiscriminatorColumn
  4. Client Servlet

Files in this tutorial

WEB-INF/resin-web.xml resin-web.xml configuration
WEB-INF/classes/META-INF/persistence.xml META-INF/persistence.xml configuration
WEB-INF/classes/example/Student.java The student bean
WEB-INF/classes/example/Prefect.java The prefect bean
WEB-INF/classes/example/QueryServlet.java The course servlet

Database Schema

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')

Bean Implementation

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.

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

Student.java
package example;

@javax.ejb.Entity (access=FIELD)
@javax.ejb.Table (name="ejb3_inherit_student")
@javax.ejb.Inheritance (discriminatorValue="student")
@javax.ejb.DiscriminatorColumn (name="type")
public class Student {
  @javax.ejb.Id (generator=AUTO)
  @javax.ejb.Column (name="id")
  private long _id;

  @javax.ejb.Basic 
  @javax.ejb.Column (name="name")
  private String _name;

  public Student()
  {
  }

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

  public String getName()
  {
    return _name;
  }

  public String toString()
  {
    return "Student[_name]";
  }
}

@Inheritance

The @Inheritance annotation marks the entity bean as supporting inheritance.

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.

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.

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.

@DiscriminatorColumn

Both SINGLE_TABLE and JOINED use a discriminator column to distinguish the classes. The @DiscriminatorColumn annotation specifies the column name. In this example, the column is "type". The default discriminator column is "TYPE".

Prefect.java
package example;

import static javax.ejb.AccessType.FIELD;

@javax.ejb.Entity (access=FIELD)
@javax.ejb.Inheritance (discriminatorValue="prefect")
public class Prefect {
  public Prefect()
  {
  }

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

  public String toString()
  {
    return "Prefect[" + getName() + "]";
  }
}

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.

Client Servlet

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.

QueryServlet.java
public void service(PrintWriter out)
  throws IOException
{
  out.println("<h3>Students</h3>");

  Query query = _manager.createQuery("SELECT o FROM Student o");
    
    for (Object student : query.listResults()) {
      out.println("student: " + student() + "<br>");
    }
  }
}

<h3>Students</h3>
Student[Harry Potter]
Prefect[Hermione Granger]
Prefect[Ron Weasley]

Try the Tutorial


CMP Many-to-Many
Tutorials
Sessions
Copyright © 1998-2006 Caucho Technology, Inc. All rights reserved.
Resin® is a registered trademark, and HardCoretm and Quercustm are trademarks of Caucho Technology, Inc.