Open In App

Hibernate – Table Per Concrete Class using XML File

Last Updated : 22 Feb, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Hibernate is capable of storing the inherited properties of an object along with its new properties in its database when an object is saved in the database. In Hibernate, inheritance between POJO classes is applied when multiple POJO classes of a module contain some common properties. In a real-time application, POJO classes of Hibernate are designed based on database table design.

If more than one POJO class has some common properties then those common properties are separated into a POJO class called the base class and the properties which are un-common are stored in the derived class. This is the concept of Hibernate Inheritance mechanism. Hibernate is capable of storing the data of a class hierarchy of an application into either one table of the database or multiple tables of the database based on database design.

Hibernate Inheritance Mapping

Object-oriented can model both “is a” and “has a” relationship. The relational model supports only the “has a” relationship between two entities. Hibernate helps in mapping such Objects with relational tables. There are three inheritance mapping strategies defined in the Hibernate.

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

Table Per Concrete Class (XML mapping)

Table per Concrete Class is one of the inheritance strategies in hibernate. If we want to keep each concrete class object of inheritance in separate tables of the database then we can proceed with the table per concrete class strategy.

In a table per Concrete Class strategy :

  • Hibernate stores each derived class object of hierarchy in a separate table of the database.
  • To inform the hibernate that apply table per concrete class inheritance mapping we need to configure <union-subclass> tag under <class> tag of hbm.xml file.
  • The discriminator column is optional.

In this strategy, each subclass table will have the subclass-specific attributes and the attributes inherited from the parent class.

Example for Table per Concrete Class 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

Hierarchy of classes

We have 3 tables Employee, P_Employee, and C_Employee. The mapping of the subclass repeats the properties of the parent class.

Creating  Database Table to persist Concrete classes:

CREATE TABLE `Employee` (

        `Id` BIGINT(20) NOT NULL AUTO_INCREMENT,

       `name` VARCHAR(50) NOT NULL DEFAULT ‘0’,

       `age` BIGINT(3) NOT NULL DEFAULT ‘0’,

        PRIMARY KEY (`id`)

)

CREATE TABLE `P_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,

     PRIMARY KEY (`id`)

)

CREATE TABLE `C_Employee` (

      `Id` BIGINT(20) NOT NULL AUTO_INCREMENT,

      `name` VARCHAR(50) NOT NULL DEFAULT ‘0’,

      `age` BIGINT(3) NOT NULL DEFAULT ‘0’,

      `hourlyrate` BIGINT(11) NULL DEFAULT NULL,

     `duration` BIGINT(11) NULL DEFAULT NULL,

     PRIMARY KEY (`id`)

)

Project Structure (IntelliJ IDEA)  for XML mapping:

Project Structure

Project Structure

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

Below is the implementation of the Employee.java file.

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(String city) { this.age = age; }
}


Below is the implementation of the P_Employee.java file.

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


Below is the implementation of the C_Employee.java file.

Java




package com.exploit.model;
  
public class C_Employee extends Employee {
    private double hourlyRate;
    private double duration;
  
    public void setDuration(double duration)
    {
        this.duration = duration;
    }
  
    public double getDuration() { return duration; }
  
    public double getHourlyRate() { return hourlyRate; }
  
    public void setHourlyRate(double hourlyRate)
    {
        this.hourlyRate = hourlyRate;
    }
}


Creating the mapping file for the Persistent class:

Below is the implementation of the employee.hbm.xml file

XML




/*package whatever //do not write package name here */
  
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  
<hibernate-mapping package="com.exploit.model">
    <class name="Employee" table="Employee">
        <id name="id">
            <generator class="increment"></generator>
        </id>
        <property name="name" column="Name"></property>
        <property name="age" column="Age"></property>
  
        <union-subclass name="com.exploit.model.P_Employee" table="P_Employee">
            <property name="salary" column="Salary"></property>
        </union-subclass>
  
        <union-subclass name="com.exploit.model.C_Employee" table="C_Employee">
            <property name="hourlyRate" column="HourlyRate"></property>
            <property name="duration" column="Duration"></property>
        </union-subclass>
  
    </class>
  
</hibernate-mapping>


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

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


We have defined only one hibernate mapping (hbm) file Employee.hbm.xml, both P_Employee and C_Employee model classes are defined within one hbm.xml file. We mapped all the classes using a simple <class> tag in hbm. This is the usual way of mapping Table Per Concrete Class using XML.



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads