In the 1990's programmers coined the term impedance mismatch to describe the difficulties in bridging the object and relational worlds. Perhaps no feature of object modeling highlights the impedance mismatch better than inheritance. There is no natural, efficient way to represent an inheritance relationship in a relational database.
		
		Luckily, EJB persistence gives you a choice of inheritance strategies,
		making the best of a bad situation.  The base entity class 
		defines the inheritance strategy for the hierarchy with the 
		Inheritance annotation.  Inheritance
		 has the following properties:  
		
				InheritanceType strategy: Enum value
				declaring the inheritance strategy for the hierarchy.
				Defaults to InheritanceType.SINGLE_TABLE.
				We detail each of the available strategies below.
				
		The corresponding XML element is inheritance, which 
		has a single attribute:
		
				strategy: One of 
				SINGLE_TABLE, JOINED,
				or TABLE_PER_CLASS.
				
The following sections describe EJB's standard inheritance strategies.
| ![[Note]](img/note.gif) | Note | 
|---|---|
| Kodo allows you to vary your inheritance strategy for each class, rather than forcing a single strategy per inheritance hierarchy. See Section 7.7, “Additional JPA Mappings” in the Reference Guide for details. | 
			The InheritanceType.SINGLE_TABLE strategy
			maps all classes in the hierarchy to the base class' table.
			

			In our model, Subscription is mapped to the
			CNTRCT.SUB table.  
			LifetimeSubscription, which extends 
			Subscription, adds its field data to this table as well.
			
Example 12.5. Single Table Mapping
@Entity
@Table(name="SUB", schema="CNTRCT")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
public class Subscription
{
    ...
}
@Entity(name="Lifetime")
public class LifetimeSubscription
    extends Subscription
{
    ...
}
The same metadata expressed in XML form:
<entity class="org.mag.subcribe.Subscription">
    <table name="SUB" schema="CNTRCT"/>
    <inheritance strategy="SINGLE_TABLE"/>
    ...
</entity>
<entity class="org.mag.subscribe.LifetimeSubscription">
    ...
</entity>
			Single table inheritance is the default strategy.  Thus, we could
			omit the @Inheritance annotation in the 
			example above and get the same result.
			
				Single table inheritance mapping is the 
				fastest of all inheritance models, since it never requires a 
				join to retrieve a persistent instance from the database.
				Similarly, persisting or updating a persistent instance 
				requires only a single INSERT or 
				UPDATE statement.  Finally, relations to 
				any class within a single table inheritance hierarchy are just 
				as efficient as relations to a base class.
				
The larger the inheritance model gets, the "wider" the mapped table gets, in that for every field in the entire inheritance hierarchy, a column must exist in the mapped table. This may have undesirable consequence on the database size, since a wide or deep inheritance hierarchy will result in tables with many mostly-empty columns.
			The InheritanceType.JOINED strategy uses a 
			different table for each class in the hierarchy.  Each table 
			only includes state declared in its class.  Thus to load a subclass
			instance, the EJB persistence implementation must read from the
			subclass table as well as the table of each ancestor class, up to
			the base entity class.
			

			PrimaryKeyJoinColumn annotations 
			tell the EJB implementation how to join each subclass table 
			record to the corresponding record in its direct superclass table.
			In our model, the LINE_ITEM.ID column joins to
			the CONTRACT.ID column.  The 
			PrimaryKeyJoinColumn annotation has 
			the following properties:
			
					String name: The name of the subclass 
					table column.  When there is a single identity field, 
					defaults to that field's column name.
					
					String referencedColumnName: The name of
					the superclass table column this subclass table column joins
					to.  When there is a single identity field, defaults to
					that field's column name.
					
					String columnDefinition: This property 
					has the same meaning as the columnDefinition
					 property on the Column 
					annotation, described in 
					Section 12.3, “Column”.
					
			The XML equivalent is the primary-key-join-column
			 element.  Its attributes
			mirror the annotation properties described above:
			
name
referenced-column-name
column-definition
			The example below shows how we use InheritanceTable.JOINED
			 and a primary key join column to map our sample model 
			according to the diagram above.  Note that a primary key join column
			is not strictly needed, because there is only one identity column, 
			and the subclass table column has the same name as the superclass 
			table column.  In this situation, the defaults suffice.  However, 
			we include the primary key join column for illustrative 
			purposes. 
			
Example 12.6. Joined Subclass Tables
@Entity
@Table(schema="CNTRCT")
@Inheritance(strategy=InheritanceType.JOINED)
public class Contract
    extends Document
{
    ...
}
public class Subscription
{
    ...
    @Entity
    @Table(name="LINE_ITEM", schema="CNTRCT")
    @PrimaryKeyJoinColumn(name="ID", referencedColumnName="ID")
    public static class LineItem
        extends Contract
    {
        ...
    }
}
The same metadata expressed in XML form:
<entity class="org.mag.subcribe.Contract">
    <table schema="CNTRCT"/>
    <inheritance strategy="JOINED"/>
    ...
</entity>
<entity class="org.mag.subscribe.Subscription.LineItem">
    <table name="LINE_ITEM" schema="CNTRCT"/>
    <primary-key-join-column name="ID" referenced-column-name="PK"/>
    ...
</entity>
			When there are multiple identity columns, you must define multiple
			PrimaryKeyJoinColumns using the aptly-named
			PrimaryKeyJoinColumns annotation.  This 
			annotation's value is an array of 
			PrimaryKeyJoinColumns.  We could rewrite 
			LineItem's mapping as:
			
@Entity
@Table(name="LINE_ITEM", schema="CNTRCT")
@PrimaryKeyJoinColumns({
    @PrimaryKeyJoinColumn(name="ID", referencedColumnName="ID")
})
public static class LineItem
    extends Contract
{
    ...
}
			In XML, simply list as many 
			primary-key-join-column elements as necessary.
			
The joined strategy has the following advantages:
Using joined subclass tables results in the most normalized database schema, meaning the schema with the least spurious or redundant data.
As more subclasses are added to the data model over time, the only schema modification that needs to be made is the addition of corresponding subclass tables in the database (rather than having to change the structure of existing tables).
Relations to a base class using this strategy can be loaded through standard joins and can use standard foreign keys, as opposed to the machinations required to load polymorphic relations to table-per-class base types, described below.
				Aside from certain uses of the table-per-class strategy 
				described below, the joined strategy is often the slowest of
				the inheritance models. Retrieving any subclass requires 
				one or more database joins, and storing subclasses requires 
				multiple INSERT or UPDATE 
				statements. This is only the case when persistence operations 
				are performed on subclasses; if most operations are performed 
				on the least-derived persistent superclass, then this mapping 
				is very fast.
				
| ![[Note]](img/note.gif) | Note | 
|---|---|
| When executing a select against a hierarchy that uses joined subclass table inheritance, you must consider how to load subclass state. Section 5.7, “Eager Fetching” in the Reference Guide describes Kodo's options for efficient data loading. | 
			Like the JOINED strategy, the 
			InheritanceType.TABLE_PER_CLASS strategy uses a different
			table for each class in the hierarchy.  Unlike the JOINED
			 strategy, however, each table includes all state for an
			instance of the corresponding class.  Thus to load a subclass
			instance, the EJB persistence implementation must only read from the
			subclass table; it does not need to join to superclass tables.
			

			Suppose that our sample model's Magazine 
			class has a subclass Tabloid.  The classes
			are mapped using the table-per-class strategy, as in the diagram 
			above.  In a table-per-class mapping, 
			Magazine's table MAG contains all 
			state declared in the base Magazine class.  
			Tabloid maps to a separate table, 
			TABLOID.  This table contains not only the state declared
			in the Tabloid subclass, but all the base 
			class state from Magazine as well.  Thus the
			TABLOID table would contain columns for 
			isbn, title, and other
			Magazine fields.  These columns would default
			to the names used in Magazine's mapping 
			metadata.  Section 12.8.3, “Embedded Mapping” will show 
			you how to use AttributeOverrides and
			AssociationOverrides to override superclass 
			field mappings.
			
Example 12.7. Table Per Class Mapping
@Entity
@Table(name="MAG")
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public class Magazine
{
    ...
}
@Entity
@Table(name="TABLOID")
public class Tabloid
    extends Magazine
{
    ...
}
And the same classes in XML:
<entity class="org.mag.Magazine">
    <table name="MAG"/>
    <inheritance strategy="TABLE_PER_CLASS"/>
    ...
</entity>
<entity class="org.mag.Tabloid">
    <table name="TABLOID"/>
    ...
</entity>
The table-per-class strategy is very efficient when operating on instances of a known class. Under these conditions, the strategy never requires joining to superclass or subclass tables. Reads, joins, inserts, updates, and deletes are all efficient in the absence of polymorphic behavior. Also, as in the joined strategy, adding additional classes to the hierarchy does not require modifying existing class tables.
				Polymorphic relations to non-leaf classes in a table-per-class
				hierarchy have many limitations.  When the concrete subclass
				is not known, the related object could be in any of the subclass
				tables, making joins through the relation impossible.  This
				ambiguity also affects identity lookups and queries; these 
				operations require multiple SQL SELECTs (one
				for each possible subclass), or a complex 
				UNION.  
				
| ![[Note]](img/note.gif) | Note | 
|---|---|
| Section 7.8.1, “Table Per Class” in the Reference Guide describes the limitations Kodo places on table-per-class mapping. | 
Now that we have covered EJB's inheritance strategies, we can update our mapping document with inheritance information. Here is the complete model:

And here is the corresponding mapping metadata:
Example 12.8. Inheritance Mapping
package org.mag;
@Entity
@IdClass(Magazine.MagazineId.class)
@Table(name="MAG")
public class Magazine
{
    @Column(length=9)
    @Id private String isbn;
    @Id private String title;
    ...
    public static class MagazineId
    {
        ...
    }
}
@Entity
@Table(name="ART", uniqueConstraints=@Unique(columnNames="TITLE"))
@SequenceGenerator(name="ArticleSeq", sequenceName="ART_SEQ")
public class Article
{
    @Id
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="ArticleSeq") 
    private long id;
    ...
}
package org.mag.pub;
@Entity
@Table(name="COMP")
public class Company
{
    @Column(name="CID")
    @Id private long id;
    ...
}
@Entity
@Table(name="AUTH")
public class Author
{
    @Id
    @GeneratedValue(strategy=GenerationType.TABLE, generator="AuthorGen")
    @TableGenerator(name="AuthorGen", table="AUTH_GEN", pkColumnName="PK",
        valueColumnName="AID")
    @Column(name="AID", columnDefinition="INTEGER64")
    private long id;
    ...
}
@Embeddable
public class Address
{
    ...
}
package org.mag.subscribe;
@MappedSuperclass
public abstract class Document
{
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private long id;
    ...
}
@Entity
@Table(schema="CNTRCT")
@Inheritance(strategy=InheritanceType.JOINED)
public class Contract
    extends Document
{
    ...
}
@Entity
@Table(name="SUB", schema="CNTRCT")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
public class Subscription
{
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private long id;
    ...
    @Entity
    @Table(name="LINE_ITEM", schema="CNTRCT")
    @PrimaryKeyJoinColumn(name="ID", referencedColumnName="ID")
    public static class LineItem
        extends Contract
    {
        ...
    }
}
@Entity(name="Lifetime")
public class LifetimeSubscription
    extends Subscription
{
    ...
}
@Entity(name="Trial")
public class TrialSubscription
    extends Subscription
{
    ...
}
The same metadata expressed in XML form:
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
    version="1.0">
    <mapped-superclass class="org.mag.subscribe.Document">
        <attributes>
            <id name="id">
                <generated-value strategy="IDENTITY"/>
            </id>
            ...
        </attributes>
    </mapped-superclass>
    <entity class="org.mag.Magazine">
        <table name="MAG"/>
        <id-class="org.mag.Magazine.MagazineId"/>
        <attributes>
            <id name="isbn">
                <column length="9"/>
            </id>
            <id name="title"/>
            ...
        </attributes>
    </entity>
    <entity class="org.mag.Article">
        <table name="ART">
            <unique-constraint>
               <column-name>TITLE</column-name>
            </unique-constraint>
        </table>
        <sequence-generator name="ArticleSeq" sequence-name="ART_SEQ"/>
        <attributes>
            <id name="id">
                <generated-value strategy="SEQUENCE" generator="ArticleSeq"/>
            </id>
           ...
        </attributes>
    </entity>
    <entity class="org.mag.pub.Company">
        <table name="COMP"/>
        <attributes>
            <id name="id">
                <column name="CID"/>
            </id>
            ...
        </attributes>
    </entity>
    <entity class="org.mag.pub.Author">
        <table name="AUTH"/>
        <attributes>
            <id name="id">
                <column name="AID" column-definition="INTEGER64"/>
                <generated-value strategy="TABLE" generator="AuthorGen"/>
                <table-generator name="AuthorGen" table="AUTH_GEN" 
                    pk-column-name="PK" value-column-name="AID"/>
            </id>
            ...
        </attributes>
    </entity>
    <entity class="org.mag.subcribe.Contract">
        <table schema="CNTRCT"/>
        <inheritance strategy="JOINED"/>
        <attributes>
            ...
        </attributes>
    </entity>
    <entity class="org.mag.subcribe.Subscription">
        <table name="SUB" schema="CNTRCT"/>
        <inheritance strategy="SINGLE_TABLE"/>
        <attributes>
            <id name="id">
                <generated-value strategy="IDENTITY"/>
            </id>
            ...
        </attributes>
    </entity>
    <entity class="org.mag.subscribe.Subscription.LineItem">
        <table name="LINE_ITEM" schema="CNTRCT"/>
        <primary-key-join-column name="ID" referenced-column-name="PK"/>
        ...
    </entity>
    <entity class="org.mag.subscribe.LifetimeSubscription" name="Lifetime">
        ...
    </entity>
    <entity class="org.mag.subscribe.TrialSubscription" name="Trial">
        ...
    </entity>
</entity-mappings>
|    |