liveBook · Manning

Inheritance strategy

As explained in Java Persistence with Spring Data and Hibernate epub

An inheritance-mapping strategy specifies how an object-oriented class hierarchy is represented in relational tables.

An inheritance strategy maps an object-oriented class hierarchy to relational tables. Because relational SQL models provide has-a relationships rather than general type inheritance, the mapping must represent polymorphism through concrete tables, discriminators, unions, or joins. section 7.0

The principal mapping choices are:

  • TABLE_PER_CLASS stores each concrete class separately. It can discard polymorphism or use SQL UNION queries to preserve runtime polymorphic behavior. section 7.0
  • SINGLE_TABLE stores the hierarchy in one denormalized table and uses a discriminator to identify supertypes and subtypes. Subclass columns generally must be nullable. section 7.0 section 7.7
  • JOINED stores the superclass and subclass data in separate tables, representing inheritance with foreign keys and retrieving polymorphic instances through SQL joins. section 7.0 section 7.7

Choose based on polymorphic queries and associations, the number of subtype attributes, normalization requirements, and the relative cost of joins versus unions. Prefer SINGLE_TABLE for simple hierarchies with few subtype properties; consider JOINED for many non-optional subtype properties and stronger normalization; evaluate TABLE_PER_CLASS when polymorphism is unnecessary or unions are preferable. section 7.7

Breaking out a subclass from SINGLE_TABLE

A BillingDetails hierarchy can use InheritanceType.SINGLE_TABLE while moving CreditCard fields into a CREDITCARD secondary table. @SecondaryTable and @Column(table = "CREDITCARD") map those fields; CREDITCARD_ID is both the primary key and a foreign key to the hierarchy table. Hibernate fetches polymorphically with a left outer join, while the separated columns can be declared NOT NULL. section 7.5

Listing 7.18 Mapping CreditCard
Path: Ch07/mapping-inheritance-mixed/src/main/java/com/manning
 /javapersistence/ch07/model/CreditCard.java
 
@Entity
@DiscriminatorValue("CC")
@SecondaryTable(
        name = "CREDITCARD",
        pkJoinColumns = @PrimaryKeyJoinColumn(name = "CREDITCARD_ID")
)
public class CreditCard extends BillingDetails {
    @NotNull
    @Column(table = "CREDITCARD", nullable = false)
    private String cardNumber;
 
    @Column(table = "CREDITCARD", nullable = false)
    private String expMonth;
 
    @Column(table = "CREDITCARD", nullable = false)
    private String expYear;
    //  . . .
}

Inspect the Java annotation mapping for moving CreditCard properties into a secondary table. section 7.5

How Java Persistence with Spring Data and Hibernate epub covers it

How deep it goes
Compares three principal strategies, explains their schema and query consequences, and demonstrates a mixed secondary-table mapping.
Examples
Uses BillingDetails and CreditCard to demonstrate a SINGLE_TABLE hierarchy extended with a CREDITCARD secondary table and outer join.
What it assumes
Assumes object-oriented inheritance and relational tables, while explaining their structural mismatch and deriving schemas from class hierarchies.
What you can do after
Evaluate and configure TABLE_PER_CLASS, SINGLE_TABLE, or JOINED mappings against query needs, subtype data, normalization, and SQL costs.
How it connects
Connects inheritance strategy with polymorphism, discriminators, foreign keys, SQL joins, SQL UNION queries, normalization, and secondary tables.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Java Persistence with Spring Data and Hibernate epub. The section links point to the parts of the book it draws on.