Class Table Inheritance Pattern


This pattern belongs to Object-Relational Structural Patterns Catalog and this Catalog belongs to Patterns of Enterprise Application Architecture.

Intent

Represents an inheritance hierarchy of classes with one table for each class.
Class Table Inheritance supports one database table per class in the inheritance structure.

Explanation



Please note in the diagram, each class have their own database table.

Player class have its own players database table.
Cricketer class have its own cricketers database table.
Footballer class have its own footballers database table.
Bowler class has its own bowlers database table.

How It Works

The straightforward thing about Class Table Inheritance is that it has one table per class in the domain model. The fields in the domain class map directly to fields in the corresponding tables. As with the other inheritance mappings, the fundamental approach of Inheritance Mappers applies.

The biggest implementation issue with Class Table Inheritance is how to bring the data back from multiple tables in an efficient manner. Obviously, making a call for each table isn’t good since you have multiple calls to the database. You can avoid this by doing a join across the various component tables; however, joins for more than three or four tables tend to be slow because of the way databases do their optimizations.

When to Use It

Class Table Inheritance, Single Table Inheritance, and Concrete Table Inheritance are the three alternatives to consider for inheritance mapping.

The strengths of Class Table Inheritance are :

  • All columns are relevant for every row so tables are easier to understand and don’t waste space.
  • The relationship between the domain model and the database is very straightforward.

The weaknesses of Class Table Inheritance are :
  • You need to touch multiple tables to load an object, which means a join or multiple queries and sewing in memory.
  • Any refactoring of fields up or down the hierarchy causes database changes.
  • The supertype tables may become a bottleneck because they have to be accessed frequently.
  • The high normalization may make it hard to understand for ad hoc queries.
  • You don’t have to choose just one inheritance mapping pattern for one class hierarchy. You can use Class Table Inheritance for the classes at the top of the hierarchy and a bunch of Concrete Table Inheritance for those lower down.

Implementation


Hibernate ORM Framework provides  inheritance mapping strategies: Table Per Concrete class using Annotation

In case of table per concrete class, tables are created as per class. But the duplicate column is added in subclass tables.

In case of Table Per Concrete class, tables are created per class. So there are no nullable values in the table. The disadvantage of this approach is that duplicate column are created in the subclass tables.
Here, we need to use @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) annotation in the parent class and @AttributeOverrides annotation in the subclasses.
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) specifies that we are using table per concrete class strategy. It should be specified in the parent class only.
@AttributeOverrides defines that parent class attributes will be overridden in this class. In table structure, parent class table columns will be added in the subclass table.
The class hierarchy is given below:
Create Hibernate model classes. we need to create the persistent classes representing the inheritance. Let's create the three classes for the above hierarchy:
import javax.persistence.*;  
  
@Entity  
@Table(name = "employee102")  
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)  
  
public class Employee {  
 @Id  
 @GeneratedValue(strategy=GenerationType.AUTO)  
    
 @Column(name = "id")  
 private int id;  
   
 @Column(name = "name")  
 private String name;  
   
 //setters and getters  
}  
import javax.persistence.*;  
  
@Entity  
@Table(name="regularemployee102")  
@AttributeOverrides({  
    @AttributeOverride(name="id", column=@Column(name="id")),  
    @AttributeOverride(name="name", column=@Column(name="name"))  
})  
public class Regular_Employee extends Employee{  
      
 @Column(name="salary")    
 private float salary;  
   
 @Column(name="bonus")     
 private int bonus;  
   
 //setters and getters  
}  
import javax.persistence.*;  
@Entity  
@Table(name="contractemployee102")  
@AttributeOverrides({  
    @AttributeOverride(name="id", column=@Column(name="id")),  
    @AttributeOverride(name="name", column=@Column(name="name"))  
})  
public class Contract_Employee extends Employee{  
      
    @Column(name="pay_per_hour")  
    private float pay_per_hour;  
      
    @Column(name="contract_duration")  
    private String contract_duration;  
  
    public float getPay_per_hour() {  
        return pay_per_hour;  
    }  
    public void setPay_per_hour(float payPerHour) {  
        pay_per_hour = payPerHour;  
    }  
    public String getContract_duration() {  
        return contract_duration;  
    }  
    public void setContract_duration(String contractDuration) {  
        contract_duration = contractDuration;  
    }  
}  

Add mapping of hbm file in the configuration file - hibernate.cfg.xml.

<?xml version='1.0' encoding='UTF-8'?>  
<!DOCTYPE hibernate-configuration PUBLIC  
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"  
          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">  
  
<!-- Generated by MyEclipse Hibernate Tools.                   -->  
<hibernate-configuration>  
    <session-factory>  
        <property name="hbm2ddl.auto">update</property>  
        <property name="dialect">org.hibernate.dialect.Oracle9Dialect</property>  
        <property name="connection.url">jdbc:oracle:thin:@localhost:1521:xe</property>  
        <property name="connection.username">system</property>  
        <property name="connection.password">oracle</property>  
<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>  
          
        <mapping class="com.javatpoint.mypackage.Employee"/>  
        <mapping class="com.javatpoint.mypackage.Contract_Employee"/>  
        <mapping class="com.javatpoint.mypackage.Regular_Employee"/>  
    </session-factory>  
</hibernate-configuration>  

Create the class that stores the persistent object. In this class, we are simply storing the employee objects in the database.

File: StoreData.java
import org.hibernate.*;  
import org.hibernate.cfg.*;  
  
public class StoreData {  
 public static void main(String[] args) {  
 AnnotationConfiguration cfg=new AnnotationConfiguration();  
 Session session=cfg.configure("hibernate.cfg.xml").buildSessionFactory().openSession();  
    
  Transaction t=session.beginTransaction();  
    
  Employee e1=new Employee();  
  e1.setName("sonoo");  
    
  Regular_Employee e2=new Regular_Employee();  
  e2.setName("Vivek Kumar");  
  e2.setSalary(50000);  
  e2.setBonus(5);  
    
  Contract_Employee e3=new Contract_Employee();  
  e3.setName("Arjun Kumar");  
  e3.setPay_per_hour(1000);  
  e3.setContract_duration("15 hours");  
    
  session.persist(e1);  
  session.persist(e2);  
  session.persist(e3);  
    
  t.commit();  
  session.close();  
  System.out.println("success");  
 }  
}  

All Design Patterns

  1. Head First Design Patterns
  2. Core J2EE Patterns
  3. Design Patterns (GOF)
  4. Patterns of EAA
  5. Concurrency Patterns
  6. GRASP Patterns

Learn Complete Java Programming Language

  1. Java Tutorial for Beginners
  2. 50 Java Keywords
  3. JDBC 4.2 Tutorial
  4. All Java/J2EE Tutorial
  5. Java 8 Tutorial
  6. Java Collections Tutorial
  7. Java Exceptions Tutorial
  8. Java Generics Tutorial
  9. Java 8 Stream API Tutorial
  10. Java Wrapper Classes
  11. Java Arrays Guide
  12. Java Multithreading Tutorial
  13. Java Concurrency Tutorial
  14. Oops Concepts Tutorial
  15. Java String API Guide
  16. Java Reflection API Tutorial
  17. Java I/O Tutorial
  18. Date and Time API Tutorial
  19. JUnit 5 Tutorial
  20. JUnit 4 Tutorial
  21. Java XML Tutorial
  22. Google GSON Tutorial

References

https://www.martinfowler.com/eaaCatalog/classTableInheritance.html

Comments