Hibernate Inheritance Mapping Tutorial

We can map the inheritance hierarchy classes with the table of the database. There are three inheritance mapping strategies defined in the hibernate:

  1. Table Per Class Hierarchy
  2. Table Per Concrete class
  3. Table Per Substring

Table Per Class Hierarchy

You can understand the problem first. I want to map the whole hierarchy in one table of the database.

table per class hierarchy in inhertance mapping

There are three class in this hierarchy. Employee is the super class for Regular_Employee class and Contract_Employee class. Let's see the mapping file for the this hierarchy.


<?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>
<class name="com.javatportal.mypackage.Employee" table="emp121" discriminator-value="emp">
<id name="id">
<generator class="increment"></generator>
</id>

<discriminator column="type" type="string"></discriminator>
<property name="name"></property>
          
<subclass name="com.javatportal.mypackage.Regular_Employee" discriminator-value="reg_emp">
<property name="salary"></property>
<property name="bonus"></property>
</subclass>
          
<subclass name="com.javatportal.mypackage.Contract_Employee" discriminator-value="con_emp">
<property name="pay_per_hour"></property>
<property name="contract_duration"></property>
</subclass>
          
</class>
          
</hibernate-mapping>

In case of table per class hierarchy an discriminator column is added by the hibernate framework that specifies the type of the record. It is mainly used to distinguish the record. To specify this, discriminator subelement of class must be specified.

The subclass subelement of class, specifies the subclass. In this case, Regular_Employee and Contract_Employee are the subclasses of Employee class.

The table structure for this hierarchy is as shown below:

Example of Table per class hierarchy

In this example we are creating the three classes and provide mapping of these classes in the employee.hbm.xml file.

1. Create the Persistent classes

You need to create the persistent classes representing the inheritance. Let's create the three classes for the above hierarchy:

Employee.java

package com.javatportal.mypackage;

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

//getters and setters
}

Regular_Employee.java

package com.javatportal.mypackage;

public class Regular_Employee extends Employee{
private float salary;
private int bonus;

//getters and setters
}
		

Contract_Employee.java

package com.javatportal.mypackage;

public class Contract_Employee extends Employee{
	private float pay_per_hour;
	private String contract_duration;

//getters and setters
}

3. Create the mapping file for Persistent class

The mapping has been discussed above for the hierarchy.

employee.hbm.xml

<?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>
<class name="com.javatportal.mypackage.Employee" table="emp121" discriminator-value="emp">
<id name="id">
<generator class="increment"></generator>
</id>

<discriminator column="type" type="string"></discriminator>
<property name="name"></property>
          
<subclass name="com.javatportal.mypackage.Regular_Employee" discriminator-value="reg_emp">
<property name="salary"></property>
<property name="bonus"></property>
</subclass>
          
<subclass name="com.javatportal.mypackage.Contract_Employee" discriminator-value="con_emp">
<property name="pay_per_hour"></property>
<property name="contract_duration"></property>
</subclass>
          
</class>
          
</hibernate-mapping>

3. Add mapping of hbm file in configuration file

Open the hibernate.cgf.xml file, and add an entry of mapping resource like this:


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

Now the configuration file will look like this:

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

<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 resource="employee.hbm.xml"/>
    </session-factory>

</hibernate-configuration>

The hbm2ddl.auto property is defined for creating automatic table in the database.

4. Create the class that stores the persistent object

In this class, we are simply storing the employee objects in the database.


package com.javatportal.mypackage;

import org.hibernate.*;
import org.hibernate.cfg.*;

public class StoreData {
public static void main(String[] args) {
	Session session=new Configuration().configure("hibernate.cfg.xml")
                        .buildSessionFactory().openSession();
	
	Transaction t=session.beginTransaction();
	
	Employee e1=new Employee();
	e1.setName("mithilesh");
	
	Regular_Employee e2=new Regular_Employee();
	e2.setName("rahul Kumar");
	e2.setSalary(50000);
	e2.setBonus(5);
	
	Contract_Employee e3=new Contract_Employee();
	e3.setName("raj 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");
}
}


Table Per Hierarchy

In table per hierarchy mapping, single table is required to map the whole hierarchy, an extra column (known as discriminator column) is added to identify the class. But nullable values are stored in the table .

Table Per Hierarchy using xml file
Table Per Hierarchy using Annotation

Table Per Concrete class

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

Table Per Concrete class using xml file
Table Per Concrete class using Annotation

Table Per Subclass

In this strategy, tables are created as per class but related by foreign key. So there are no duplicate columns.

Table Per Subclass using xml file
Table Per Subclass using Annotation