Hibernate – Inheritance Mapping

The inheritance hierarchy can be seen easily in the table of the database. In Hibernate we have three different strategies available for Inheritance Mapping

  • Table Per Hierarchy
  • Table Per Concrete class
  • Table Per Subclass

Hierarchy can be diagrammatically seen easily.

 

In this article let us see about Table Per Hierarchy using XML. It can be done using annotation as well. Here the whole hierarchy is getting mapped by a single table itself. A discriminator(differntiating) column is created in the table to identify the class. Let us take a sample between Regular worker and contract worker which are mapped from worker

Example Project

MySQL table structure

create table worker( workerId int auto_increment, workerName varchar(25), salary float, additionalBenifits int, pricePerHour float, contractPeriod varchar(25),
Primary key (workerId)
);

MySQL table named ‘worker’ is created with the necessary columns. By seeing the column names we can come to know that workerId and workerName should be available in the Main Worker class. salary and additionalBenifits would be for RegularWorker. pricePerHour and contractPeriod would be for ContractWorker.

Project Structure:

Project Structure

 

As this is the maven project, let us add pom.xml

XML

  <modelVersion>4.0.0</modelVersion>

  <groupId>Inheritence</groupId>

  <artifactId>Inheritence</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>

        

        <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>

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. Let us see worker.hbm.xml

worker.hbm.xml

XML

<?xml version='1.0' encoding='UTF-8'?>  

<!DOCTYPE hibernate-mapping PUBLIC  

          "-//Hibernate/Hibernate Mapping DTD 5.3//EN"  

    

<hibernate-mapping>  

     

      

    <class name="com.gfg.hierarchy.Worker" table="worker" discriminator-value="worker">  

      <id name="workerId">  

          <generator class="increment"></generator>  

      </id>  

  

      

           

           

      <discriminator column="type" type="string"></discriminator>  

      <property name="workerName"></property>  

  

       

            

      <subclass name="com.gfg.hierarchy.RegularWorker" discriminator-value="regularworker">  

        <property name="salary"></property>  

        <property name="additionalBenifits"></property>  

      </subclass

  

       

            

            

      <subclass name="com.gfg.hierarchy.ContractWorker" discriminator-value="contractworker">  

        <property name="pricePerHour"></property>  

        <property name="contractPeriod"></property>  

      </subclass>  

  

    </class>  

              

</hibernate-mapping>

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'?>  

<hibernate-configuration>

    <session-factory>

        

              

              

        <property name="hbm2ddl.auto">update</property>  

        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>

        <property name="connection.username">root</property>

        <property name="connection.password">admin</property>

          

          

              

        <mapping resource="worker.hbm.xml" /> 

    </session-factory>

</hibernate-configuration>

Let us see the equivalent bean classes

Worker.java

Java

public class Worker {

    

    

    

    

    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 {

    

    

    

    

    private float salary;

    private int additionalBenifits;

  

    public float getSalary() {

        return salary;

    }

  

    public void setSalary(float salary) {

        this.salary = salary;

    }

  

    public int getAdditionalBenifits() {

        return additionalBenifits;

    }

  

    public void setAdditionalBenifits(int additionalBenifits) {

        this.additionalBenifits = additionalBenifits;

    }

  

}

ContractWorker.java

Java

public class ContractWorker extends Worker{ 

    

    

    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.

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();  

       

    

    Worker worker=new Worker();  

    worker.setWorkerName("Rachel Green");  

        

    

    RegularWorker regularWorker=new RegularWorker();  

    regularWorker.setWorkerName("Ross");  

    regularWorker.setSalary(100000);  

    regularWorker.setAdditionalBenifits(50);  

        

    

    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

 

We can verify the same by querying the DB data of the worker table. On execution of the above code, 3 different records are inserted. The flow is following as the Table per hierarchy and hence all the data will be inserted in a single table only, In this example use “worker” as the table name and “type” as the discriminator column, and below is the output

 

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).