Hibernate - Inheritance Mapping

Last Updated : 30 Mar, 2026

Inheritance Mapping in Hibernate allows us to map object-oriented inheritance (Java classes) into relational database tables. It helps represent IS-A relationships between entities in a database-friendly way.

  • Supports mapping of parent-child class hierarchy
  • Provides multiple strategies to store inheritance in DB
  • Helps maintain clean and scalable design

Inheritance Strategies in Hibernate

Hibernate provides three strategies:

  1. Table Per Hierarchy (Single Table Strategy)
  2. Table Per Subclass (Joined Strategy)
  3. Table Per Concrete Class (Union Strategy)

Step-by-Step Project Implementation

Step 1: Create Maven Project

  • Create a Maven Project in Eclipse/IntelliJ.
  • Add Dependencies in pom.xml
Java
<project xmlns="https://maven.apache.org/POM/4.0.0"
         xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance" 
         xsi:schemaLocation="https://maven.apache.org/POM/4.0.0
                             https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>Inheritance</groupId>
  <artifactId>Inheritance</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <build>
    <sourceDirectory>src</sourceDirectory>
    <resources>
      <resource>
        <directory>src</directory>
        <excludes>
          <exclude>**/*.java</exclude>
        </excludes>
      </resource>
    </resources>
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.8.1</version>
        <configuration>
          <release>9</release>
        </configuration>
      </plugin>
    </plugins>
  </build>
  <dependencies>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.4.15.Final</version>
        </dependency>
        <!-- As we are connecting with MySQL, this is needed -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.34</version>
        </dependency>
    </dependencies>
    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
</project>


Project Structure:

Project Structure

Step 2: Create Database Table

CREATE TABLE worker(

workerId INT AUTO_INCREMENT,
workerName VARCHAR(25),
salary FLOAT,
additionalBenefits INT,
pricePerHour FLOAT,
contractPeriod VARCHAR(25),
type VARCHAR(20),
PRIMARY KEY (workerId)
);

Here:

  • workerId, workerName: Belong to the Parent (Worker) class
  • salary, additionalBenefits: Belong to the RegularWorker class
  • pricePerHour, contractPeriod: Belong to the ContractWorker class
  • type: Used as the Discriminator column to identify class type

Step 3: Create Mapping File

As all the columns are specified in a single table itself, then they should be distinguished by means of a discriminator column. It is specified in the hbm file.

worker.hbm.xml

XML
<?xml version='1.0' encoding='UTF-8'?>  
<!DOCTYPE hibernate-mapping PUBLIC  
          "-//Hibernate/Hibernate Mapping DTD 5.3//EN"  
          "https://hibernate.sourceforge.net/hibernate-mapping-5.3.dtd">  
  
<hibernate-mapping>  
   
      <!-- Referring to Worker bean -->
    <class name="com.gfg.hierarchy.Worker" table="worker" discriminator-value="worker">  
      <id name="workerId">  
          <generator class="increment"></generator>  
      </id>  

      <!-- As all columns are kept in the same table, we need to have
           a separate column named "type". It should inform about the 
           type of worker. Here it can be Worker/RegularWorker/ContractWorker -->
      <discriminator column="type" type="string"></discriminator>  
      <property name="workerName"></property>  

       <!-- RegularWorker is inherited from Worker and hence it should be denoted with subclass
            and its discriminator-value="regularworker" -->
      <subclass name="com.gfg.hierarchy.RegularWorker" discriminator-value="regularworker">  
        <property name="salary"></property>  
        <property name="additionalBenefits"></property>  
      </subclass> 

       <!-- ContractWorker is inherited from Worker and hence
            it should be denoted with subclass
            and its discriminator-value="contractworker" -->
      <subclass name="com.gfg.hierarchy.ContractWorker" discriminator-value="contractworker">  
        <property name="pricePerHour"></property>  
        <property name="contractPeriod"></property>  
      </subclass>  

    </class>  
            
</hibernate-mapping>  

Step 4: Create Hibernate Configuration

We are using MYSQL and hence those configurations need to be specified in hibernate.cfg.xml

hibernate.cfg.xml

XML
<?xml version='1.0' encoding='UTF-8'?>  
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "https://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <!--  As we are connecting mysql, those driver classes, 
              database name, username and password are specified
              Please change the information as per your requirement -->
        <property name="hbm2ddl.auto">update</property>  
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost:3306/geeksforgeeks?serverTimezone=UTC</property>        
        <property name="connection.username">root</property>
        <property name="connection.password">admin</property>
        
          <!--  We are going to connect worker.hbm.xml which has 
              the table information about worker which is present in mysql -->
        <mapping resource="worker.hbm.xml" /> 
    </session-factory>
</hibernate-configuration>

Step 5: Create Entity Classes

Let us see the equivalent bean classes

Worker.java

Java
public class Worker {
    
    // Only the columns required for Worker is specified
    // As RegularWorker and ContractWorker are extended 
    // from this, those required columns 
    // are specified in those tables
    
    private int workerId;
    private String workerName;

    public int getWorkerId() {
        return workerId;
    }

    public void setWorkerId(int workerId) {
        this.workerId = workerId;
    }

    public String getWorkerName() {
        return workerName;
    }

    public void setWorkerName(String workerName) {
        this.workerName = workerName;
    }
}

RegularWorker.java

Java
public class RegularWorker extends Worker {
    
    // We are specifying only the columns
    // required for RegularWorker
    // Hence salary and additionalBenefits
    // are specified here
    
    private float salary;
    private int additionalBenefits;

    public float getSalary() {
        return salary;
    }

    public void setSalary(float salary) {
        this.salary = salary;
    }

    public int getAdditionalBenefits() {
        return additionalBenefits;
    }

    public void setAdditionalBenefits(int additionalBenefits) {
        this.additionalBenefits = additionalBenefits;
    }

}

ContractWorker.java

Java
public class ContractWorker extends Worker{ 
    
    // only the columns required for 
    // ContractWorker are specified here
    
    private float pricePerHour;  
    private String contractPeriod;
    public float getPricePerHour() {
        return pricePerHour;
    }
    public void setpricePerHour(float pricePerHour) {
        this.pricePerHour = pricePerHour;
    }
    public String getContractPeriod() {
        return contractPeriod;
    }
    public void setContractPeriod(String contractPeriod) {
        this.contractPeriod = contractPeriod;
    }   
}  

worker.hbm.xml file is the very important key file and for "Table per hierarchy" , discriminator column is the very essential element of it.

Step 6: Create Main Class

  • Creates objects of all classes
  • Saves them in DB

TablePerHierarchyWayOfStoringData.java

Java
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;  
public class TablePerHierarchyWayOfStoringData {  
public static void main(String[] args) {  
    
    StandardServiceRegistry standardServiceRegistry = new StandardServiceRegistryBuilder().configure("hibernate.cfg.xml").build();
    Metadata metaData=new MetadataSources(standardServiceRegistry).getMetadataBuilder().build();
    
    SessionFactory factory=metaData.getSessionFactoryBuilder().build();
    Session session=factory.openSession();
  
    Transaction transaction=session.beginTransaction();  
     
    // This will indicate for  the Worker class 
    Worker worker=new Worker();  
    worker.setWorkerName("Rachel Green");  
      
    // This will indicate for  the RegularWorker class
    RegularWorker regularWorker=new RegularWorker();  
    regularWorker.setWorkerName("Ross");  
    regularWorker.setSalary(100000);  
    regularWorker.setAdditionalBenefits(50);  
      
    // This will indicate for  the ContractWorker class
    ContractWorker contractWorker=new ContractWorker();  
    contractWorker.setWorkerName("Joey Tribbiani");  
    contractWorker.setpricePerHour(5000);  
    contractWorker.setContractPeriod("25 hours");  
      
    session.persist(worker);  
    session.persist(regularWorker);  
    session.persist(contractWorker);  
      
    transaction.commit();  
    session.close();  
    System.out.println("success. We can see 3 records got inserted in worker table and type is the discriminator column");  
}  
}  

Execution of the program and its output

All records can be verified by querying the worker table. Since the Table Per Hierarchy strategy is used, all data is stored in a single table. The type column acts as a discriminator to identify each subclass, and 3 records are inserted accordingly.

Additionally, inheritance can be seen via Table Per Concrete class (tables are created as per class) and Table Per Subclass(tables are created as per class but related by the foreign key).

Comment