Hibernate - Table Per Hierarchy using XML File

Last Updated : 10 Apr, 2026

Table per Hierarchy is one of the inheritance strategies in hibernate. In this strategy, the entire hierarchy is mapped to a single table. All attributes of all the classes in the hierarchy are stored in a single table. In a table per Hierarchy strategy

  • A string value is stored to identify the subclass of each row
  • Uses a discriminator column to store subclass type
  • Configure using <sub-class> tag inside <class> in hbm.xml

Null values will be stored in the table for which there is no column applicable. A discriminator uniquely identifies the base type of the class hierarchy.

Example for Table per Hierarchy Strategy

Let's suppose we have a class Employee with subclasses as P_Employee and C_Employee. Following the class diagram and relationship of these classes.

hierarchy_of_classes
Table per Hierarchy

Step 1: Create Maven Project

  • Open IntelliJ IDEA -> New Project ->Maven
  • Set GroupId & ArtifactId

Add Dependencies (pom.xml)

XML
<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>TablePerHierarchyXML</groupId>
    <artifactId>TablePerHierarchyXML</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>TablePerHierarchyXML</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
      
        <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.2.6.Final</version>
        </dependency>
      
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>6.0.5</version>
        </dependency>
    </dependencies>
</project>

Project Structure

Screenshot97-660x652
Project-Structure

Step 2: Create Database Table

  • We have three classes: Employee (superclass), P_Employee, and C_Employee (subclasses).
  • In Table Per Hierarchy strategy, all attributes of these classes are stored in a single table (Employee).

Creating  Database Table to persist class Hierarchy:

CREATE TABLE `Employee` (

       `id` BIGINT(20) NOT NULL AUTO_INCREMENT,

      `name` VARCHAR(50) NOT NULL DEFAULT '0',

      `age` BIGINT(3) NOT NULL DEFAULT '0',

     `salary` BIGINT(11) NULL DEFAULT NULL,

     `hourlyrate` BIGINT(11) NULL DEFAULT NULL,

    `duration` BIGINT(11) NULL DEFAULT NULL,

    `discriminator` VARCHAR(20) NOT NULL,

     PRIMARY KEY (`id`)

)

The Employee table will store objects of all three classes Employee, P_Employee and C_Employee.

Step 3: Create Model Classes

Creating the Employee, P_Employee, and C_Employee classes for the above hierarchy:

Employee.java

Java
package com.exploit.model;

public class Employee {
  
    private int id;
    private String name;
    private int age;

    public int getId() { return id; }

    public void setId(int id) { this.id = id; }

    public String getName() { return name; }

    public void setName(String name) { this.name = name; }

    public int getAge() { return age; }

    public void setAge(int age) { this.age = age; }
}

P_Employee.java

Java
package com.exploit.model;

public class P_Employee extends Employee {
    private double salary;

    public double getSalary() { return salary; }

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

C_Employee.java

Java
package com.exploit.model;

public class C_Employee extends Employee {
    private double hourlyRate;
    private double duration;

    public double getDuration() { return duration; }

    public void setDuration(double duration)
    {
        this.duration = duration;
    }

    public double getHourlyRate() { return hourlyRate; }

    public void setHourlyRate(double hourlyRate)
    {
        this.hourlyRate = hourlyRate;
    }
}

Step 4: Create Mapping File (employee.hbm.xml)

  • Creating the mapping file for the Persistent class
  • <class> -> defines base class
  • <discriminator> -> identifies subclass
  • <subclass> -> maps child classes

employee.hbm.xml.

Java
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.exploit.model">
    <class name="Employee" table="Employee" discriminator-value="E">
        <id name="id">
            <generator class="increment"></generator>
        </id>

        <discriminator column="discriminator" type="string"></discriminator>
        <property name="name"></property>
        <property name="age"></property>

        <subclass name="com.exploit.model.P_Employee" extends="Employee" discriminator-value="PE">
            <property name="salary"></property>
        </subclass>

        <subclass name="com.exploit.model.C_Employee" extends="Employee" discriminator-value="CE">
            <property name="hourlyRate"></property>
            <property name="duration"></property>
        </subclass>

    </class>

</hibernate-mapping>

Discriminator Values:

  • E ->Employee
  • PE -> P_Employee
  • CE ->C_Employee

Hibernate will put the appropriate discriminator values based on the record we are persisting.

Step 5: Configure Hibernate

Adding the mapping of hbm.xml file in the hibernate configuration file

  • dialect -> DB-specific SQL generation
  • show_sql ->prints SQL in console
  • hbm2ddl.auto=update -> auto table update
  • Mapping file must be registered

Below is the implementation of the hibernate.cfg.xml file:

XML
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

    <session-factory>

        <!-- Database connection properties -->
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="connection.url">jdbc:mysql://localhost/javainsimpleway</property>
        <property name="connection.username">root</property>
        <property name="connection.password">toor</property>

        <!-- JDBC connection pool (using the built-in) -->
        <property name="connection.pool_size">1</property>

        <!-- SQL dialect -->
        <property name="dialect">org.hibernate.dialect.MySQLDialect</property>

        <!-- Disable the second-level cache -->
        <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>

        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">true</property>

        <!-- Format the generated Sql -->
        <property name="format_sql">true</property>

        <!-- Dont Drop and re-create the database schema on startup,Just update it -->
        <property name="hbm2ddl.auto">update</property>

        <mapping resource="com/exploit/mapping/employee.hbm.xml"/>

    </session-factory>

</hibernate-configuration>

Step 6: Create Main Class

Creating the class that stores the persistent object

  • Same persist() for all classes
  • Hibernate automatically sets discriminator
  • No need to manually insert type

Below is the implementation of the Main.java file: 

Java
package com.exploit.db;

import com.exploit.model.C_Employee;
import com.exploit.model.Employee;
import com.exploit.model.P_Employee;
import com.exploit.util.HibernateUtil;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;

public class Main {
    public static void main(String[] args)
    {
        // Get session factory using Hibernate Util class
        SessionFactory sessionFactory
            = HibernateUtil.getSessionFactory();
      
        // Get session from Session factory
        Session session = sessionFactory.openSession();

        // Begin transaction
        Transaction transaction
            = session.beginTransaction();

        // Creating Employee base class record
        Employee employee = new Employee();
        employee.setName("KirikoChan");
        employee.setAge(19);

        // Creating Permanent Employee subclass record
        P_Employee permanentEmployee = new P_Employee();
        permanentEmployee.setName("Saili.H");
        permanentEmployee.setAge(20);
        permanentEmployee.setSalary(30000);

        // Creating Contract Employee subclass record
        C_Employee contractEmployee = new C_Employee();
        contractEmployee.setName("ChikkoRita");
        contractEmployee.setAge(18);
        contractEmployee.setDuration(8.5);
        contractEmployee.setHourlyRate(2000);

        // persist all the employee records
        session.persist(employee);
        session.persist(permanentEmployee);
        session.persist(contractEmployee);

        // Commit the transaction and close the session
        transaction.commit();
        session.close();
        System.out.println(
            "Employee records successfully persisted.");
    }
}

Step 7: Output in Database

idnameagesalaryhourlyratedurationdiscriminator
1KirikoChan19NULLNULLNULLE
2Saili.H2030000NULLNULLPE
3ChikkoRita18NULL20008.5CE

This is the usual way of mapping Table Per Hierarchy using XML.

Comment