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, JDOR provides very flexible object-relational mapping of 
		inheritance trees, making the best of a bad situation.  Each class in
		an inheritance hierarchy can use the inheritance
		element to describe its inheritance mapping.  This element has a 
		single attribute: strategy.  In the list that
		follows, we examine JDOR's standard inheritance strategies.  Some
		vendors may define additional proprietary strategies.
		
| ![[Note]](img/note.gif) | Note | 
|---|---|
| Kodo does not define any non-standard inheritance models, but does allow you to create your own custom mappings. See the Reference Guide's Section 7.10, “Custom Mappings” for details on writing custom inheritance strategies and pluggin them in to Kodo. | 
			The subclass-table inheritance strategy indicates
			that the current class is not mapped to any table at all, and that
			all of its fields must be mapped by subclasses into their own
			tables.  This strategy is typically used with abstract base classes
			that are not represented in the relational schema.
			Classes that declare an inheritance strategy of 
			subclass-table should not define the 
			class element's table 
			attribute, nor should they attempt to define mappings for any 
			fields.
			

			In our model, the abstract Contract class
			uses the subclass-table inheritance strategy.
			Contract's two direct subclasses, 
			Subscription and 
			LineItem, each map all of 
			Contract's fields into their own tables.
			
Example 15.4. subclass-table Mapping
<class name="Contract">
    <inheritance strategy="subclass-table"/>
    ...
</class>
| ![[Note]](img/note.gif) | Note | 
|---|---|
| The pattern of mapping the fields of an abstract, unmapped base class into the tables of each subclass is often referred to as a horizontal or distributed inheritance mapping. | 
				An advantage of using the subclass-table 
				strategy for abstract base classes is that properties common 
				to multiple persistent subclasses can be defined in the 
				superclass without having to suffer the performance 
				consequences and relational design restrictions inherent in 
				other strategies (which we will examine shortly).  Persisting 
				and modifying instances of subclasses is efficient, typically 
				only requiring a single INSERT or 
				UPDATE statement.  Loading
				relations to these subclasses is also efficient.
				
				
				Though relations to mapped subclasses of a 
				subclass-table class are very efficient, 
				relations to the unmapped base class itself are equally
				inefficient. When the concrete subclass
				is not known, the related object could be in any of the 
				subclass tables, making joins through the relation 
				impossible.  Subclasses can even use repeated primary key
				values, forcing the JDOR implementation to record more than just
				the related primary key values in the database.
				
				This ambiguity also affects queries and identity lookups: 
				queries against a subclass-table base class 
				require either multiple SELECT statements 
				(one for each mapped subclass), or a complex SQL 
				UNION.
				
| ![[Note]](img/note.gif) | Note | 
|---|---|
| 
					Kodo provides metadata extensions you can use to indicate
					that a field declared as a relation to a base class is
					actually a relation to a specific subclass.  These 
					extensions often alleviate the need for mapping a relation
					to a  
					When a relation to a  | 
				Here are some additional caveats to consider when using
				the subclass-table inheritance mapping:
				
						
						Declaring classes abstract.
						You are not required to make all subclass-table
						 classes abstract.  However, we recommend 
						that you do so, as any attempt to persist a 
						subclass-table base class instance 
						will result in an exception on flush.
						
						
						Application identity.
						When a subclass-table superclass
						uses application identity, you must observe one of the 
						following two restrictions:
						
								The primary key values in each of the tables
								that extend the subclass-table
								 superclass must be unique. In our
								model, that means that there can be no row in
								CNTRCT.SUB with the same 
								primary key value as a row in
								CNTRCT.LINE_ITEM.
								This is because a call to
								getObjectById with an
								application identity instance cannot identify
								which subclass the ID is associated with.
								
Rather than having a single application identity class associated with the entire class hierarchy, each subclass declares its own application identity class. The inheritance hierarchy of the application identity classes must exactly match the inheritance hierarchy of the persistent classes they represent, as discussed in Section 4.5.2.1, “Application Identity Hierarchies”.
			The new-table inheritance strategy employs a
			new table to hold the fields of the class.  You must specify the 
			table name in the class element's 
			table attribute. 
			
			new-table is the default strategy for base 
			persistent classes and for subclasses of subclass-table
			 classes.  Classes that extend non-subclass-table
			 base classes can also use this strategy to map their 
			fields to a new table, rather than to the superclass table.  The
			subclass table might contain only subclass state, or might re-map
			all superclass state as well.  
			
				When the subclass table only contains subclass state, the JDOR 
				implementation must be able to link corresponding records in 
				the superclass and subclass tables together to retrieve all of 
				the persistent state for a subclass
				instance.  You tell the JDOR implementation how to 
				do this by nesting a join element in your 
				inheritance element.  Thus, this is often
				referred to as a joined inheritance
				strategy.
				
				As its name implies, the join element maps a 
				logical foreign key from the subclass table to the superclass 
				table.  It has a column attribute and nested
				column elements for representing the 
				subclass table's foreign key columns.  
				Section 15.7, “Joins” demonstrated how to
				use columns to map joins.  Typically, the 
				subclass table's foreign key columns are also that table's 
				primary key columns.  
				

				All of the classes in our model except Contract
				 and LifetimeSubscription 
				(not pictured) use the new-table strategy.  
				Most of these classes are either base classes or direct 
				subclasses of Contract, a 
				subclass-table class.  In these cases, the 
				new-table strategy is the default.  
				TrialSubscription, however, extends 
				Subscription, which is itself mapped to 
				a table.  Therefore, TrialSubscription 
				could have mapped its fields to 
				Subscription's table. 
				

				Instead, TrialSubscription maps its 
				declared fields to the CNTRCT.TRIAL_SUB 
				table, and joins to the CNTRCT.SUB table for
				base class state.  The join is made by linking the 
				CNTRCT.TRIAL_SUB.ID foreign key column to the 
				CNTRCT.SUB.ID primary key column.  The 
				example below shows how to represent this in mapping metadata.
				
Example 15.5. Joined Subclass Tables
<class name="TrialSubscription" table="CNTRCT.TRIAL_SUB">
    <inheritance strategy="new-table">
       <join>
           <column name="ID" target="CNTRCT.SUB.ID"/> 
       </join>
    </inheritance>
    ...
</class>
That is the long version, however. JDOR is smart enough to default the target table to the superclass table, and we can apply join shortcuts to yield a much more concise representation:
<class name="TrialSubscription" table="CNTRCT.TRIAL_SUB">
    <inheritance strategy="new-table">
       <join column="ID"/>
    </inheritance>
    ...
</class>
					If you want to map a class to a table and none of the 
					superclasses of that class are themselves mapped to a table
					(or the class has no persistent superclasses), then the 
					new-table strategy is your only choice.
					It is only meaningful to discuss the advantages and 
					disadvantages of the new-table strategy 
					for classes that have a superclass mapped to a different 
					table.  For example, our model's 
					TrialSubscription class extends 
					Subscription, yet maps its declared fields to a
					different table.  We could have mapped 
					TrialSubscription's fields to 
					Subscription's table; what made us 
					choose to to use a separate joined table instead?
					
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 the
							new-table strategy can be loaded
							through standard joins and can use standard foreign 
							keys, as opposed to the machinations required to 
							load relations to subclass-table
							base types.
							
					Using multiple joined tables slows things down.
					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 new-table strategy, the 
				table-per-class new-table
				 strategy maps a subclass to its own table.
				Unlike the joined strategy, however, the subclass table 
				includes all state for an instance of the corresponding class.
				Thus to load a subclass instance, the JDOR 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.  
				
Example 15.6. Table Per Class Mapping
<class name="Tabloid" table="TABLOID">
    <inheritance strategy="new-table"/>
    <field name="Magazine.isbn" column="ISBN"/>
    <field name="Magazine.title" column="TITLE"/>
    ...
    <field name="data" column="TAB_DATA"/>
</class>
				Notice that only the lack of a join 
				within the inheritance element differentiates
				a table-per-class strategy from a joined strategy.  Also, notice
				that a table-per-class subclass explicitly re-maps all of its
				inherited fields into its own table.  
				
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 a non-leaf classes in a 
					table-per-class hierarchy have many limitations.
					In some ways, they are similar to relations to a 
					subclass-table base class.  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. | 
			superclass-table is the default strategy for 
			subclasses of new-table and other 
			superclass-table classes.  In this strategy,
			the subclass' fields are mapped to superclass' table.  Classes
			that use the superclass-table inheritance
			strategy should not specify the class element's 
			table attribute. 
			

			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 15.7. superclass-table Mapping
<class name="LifetimeSubscription">
    <inheritance strategy="superclass-table"/>
    ...
</class>
				superclass-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 superclass-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.
Now that we have covered JDOR'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 15.8. Inheritance Mapping
<?xml version="1.0"?>
<orm>
    <package name="org.mag">
        <sequence name="ArticleSeq" datastore-sequence="ART_SEQ"/> 
        <class name="Magazine" table="MAG">
            <!-- not strictly necessary, since this is the default -->
            <inheritance strategy="new-table"/>
            <field name="isbn">
                <column name="ISBN" jdbc-type="char" length="15"/>
            </field>
            <field name="title" column="TITLE"/>
            ...
        </class>
        <class name="Article" table="ART">
            <!-- not strictly necessary, since this is the default -->
            <inheritance strategy="new-table"/>
            <field name="id" column="ID"/>
            ...
        </class>    
    </package>
    <package name="org.mag.pub">
        <sequence name="AuthorSeq" factory-class="Author$SequenceFactory"/>
        <class name="Company" table="COMP">
            <datastore-identity column="CID" strategy="autoassign"/>
            <!-- not strictly necessary, since this is the default -->
            <inheritance strategy="new-table"/>
            ...
        </class>    
        <class name="Author" table="AUTH">
            <datastore-identity sequence="AuthorSeq">
                <column name="AID" sql-type="INTEGER64"/>
            </datastore-identity>
            <!-- not strictly necessary, since this is the default -->
            <inheritance strategy="new-table"/>
            ...
        </class>
    </package>
    <package name="org.mag.subscribe">
        <sequence name="ContractSeq" strategy="transactional"/> 
        <class name="Contract">
            <inheritance strategy="subclass-table"/>
            ...
        </class>
        <class name="Subscription" table="CNTRCT.SUB">
            <!-- not strictly necessary, since this is the default -->
            <inheritance strategy="new-table"/>
            <field name="Contract.id" column="ID"/>
            ...
        </class>
        <class name="LifetimeSubscription">
            <!-- not strictly necessary, since this is the default -->
            <inheritance strategy="superclass-table"/>
            ...
        </class>
        <class name="TrialSubscription" table="CNTRCT.TRIAL_SUB">
            <inheritance strategy="new-table">
                <join column="ID"/>
            </inheritance>
            ...
        </class>
        <class name="Subscription$LineItem" table="CNTRCT.LINE_ITEM">
            <!-- not strictly necessary, since this is the default -->
            <inheritance strategy="new-table"/>
            <field name="Contract.id" column="ID"/>
            ...
        </class>
    </package>
</orm>
|    |