TopLink JPA: How-To Define Inheritance

Version: 05/14/08

Introduction

In JPA, an entity class may inherit from another entity class its behaviour and state. The behaviour and state become shared between entity classes enabling the inheritance of existing mappings--you would only need to define mappings for a new state.

There are several types of inheritance. Two of these types-- single table inheritance and joined table inheritance--have many similarities: their object model is the same; they can be configured using either annotations or XML; for both types, a discriminator column (a single column used for distinguishing to which class type a database row belongs) is required on the database. The underlying database structure of the single table and joined table inheritance is, however, slightly different.

 

Single Table Inheritance

 

In the single table inheritance, the entire class hierarchy is represented by a single table. As the following example shows, the Project class and the LargeProject class map to the same PROJECT table:

PROJECT
IDTYPEDESCRIPTIONBUDGET
1
P
small project
 
2
L
large project
1000000

public class Project {

protected BigInteger id;
protected String description;

...

}

public class LargeProject extends Project {

protected BigInteger budget;

...

}

The LargeProject class inherits most of its data from the Project class, with the exception of budget, which the LargeProject adds. The discriminator column ( TYPE) is added to the table to distinguish between the stored instances.

You can configure the single table inheritance using either annotations or XML.

Annotations

The following example shows the mapping of the Project and LargeProject classes to the PROJECT table using annotations:

@Entity
@Table(name="PROJECT")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="TYPE", discriminatorType=DiscriminatorType.STRING,length=20)
@DiscriminatorValue("P")
public class Project {

@Id protected BigInteger id;
protected String description;
...

}


@Entity
@DiscriminatorValue("L")
public class LargeProject extends Project {

protected BigInteger budget;
...

}

XML

You can also map the Project and LargeProject classes to the PROJECT table using XML, as the following example demonstrates:

<entity name="Project" class="Project" access="FIELD">

<table name="PROJECT"/>
<inheritance strategy="SINGLE_TABLE"/>
<discriminator-value>P</discriminator-value>
<discriminator-column name="TYPE"/>
<attributes>
<id name="id"><column name="ID"/></id>
</attributes>
</entity>

<entity name="LargeProject" class="LargeProject" access="FIELD">
<discriminator-value>L</discriminator-value>
</entity>

Joined Table Inheritance

 

In the joined table inheritance, each class shares data from the root table. In addition, each subclass defines its own table that adds its extended state. The following example shows two tables, PROJECT and L_PROJECT, as well as two classes, Project and LargeProject:

PROJECT
IDTYPEDESCRIPTION
1
P
small project
2
L
large project


L_PROJECT
IDBUDGET
2
1000000

public class Project {

protected BigInteger id;
protected String description;

...

}

public class LargeProject extends Project {

protected BigInteger budget;

...

}

Similar to the example of the single table inheritance, the preceding joined table example demonstrates how the shared data is stored in a single table. The newly defined fields, however, are stored in a separate table.

You can configure the joined table inheritance using either annotations or XML.

Annotations

The following example shows the mapping of the Project and LargeProject classes to the PROJECT and L_PROJECT tables using annotations:

@Entity
@Table(name="PROJECT")
@Inheritance(strategy=InheritanceType.JOINED)
@DiscriminatorColumn(name="TYPE", discriminatorType=DiscriminatorType.STRING,length=20)
@DiscriminatorValue("P")
public class Project {

}

@Entity
@Table(name="L_PROJECT")
@DiscriminatorValue("L")
public class LargeProject extends Project {

protected BigInteger budget;
...
}

XML

You can also map the Project and LargeProject classes to the PROJECT and L_PROJECT tables using XML, as the following example shows:

<entity name="Project" class="Project" access="FIELD">

<table name="PROJECT"/>
<inheritance strategy="JOINED"/>
<discriminator-value>P</discriminator-value>
<discriminator-column name="TYPE"/>
<attributes>
<id name="id"><column name="ID"/> </id>
</attributes>

</entity>

<entity name="LargeProject" class="LargeProject" access="FIELD">

<table name="L_PROJECT"/>
<discriminator-value>L</discriminator-value>

</entity>

Summary

This How-To document demonstrated the ways to define inheritance for entities using annotations and XML.