Blog Image

Table Per Class Hierarchy Using Xml Config.  

In this blog, we show you how to use Hibernate to implement "Inheritance Mapping Table Per Class Hierarchy relationship by using Xml Configuration approach. This is the most common use case we often encounter in an Application Development.

Below is the example for Inheritance Mapping Table Per Class Hierarchy Using Xml Configuration approach.

Lets see Inheritance Mapping example:
Technologies used :-
1) java (1.8).
2) maven (3.5.2).
3) hibernate (5.2.12).
4) MySql (5.7.21).

Below is the table structure.

Execute this query for creating tables in Database(MySql).
CREATE TABLE `employee_details` (
  `employee_id` int(11) NOT NULL,
  `employee_type` varchar(255) NOT NULL,
  `employee_name` varchar(255) DEFAULT NULL,
  `salary` float DEFAULT NULL,
  `bonus` int(11) DEFAULT NULL,
  `pay_per_hour` float DEFAULT NULL,
  `contract_duration` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`employee_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8$$

Project Structure

Below is the maven project structure with packages and java/resource files.

Entity Classes
EmployeeDetails.java
package com.tpch.entities;

public class EmployeeDetails {
    protected int employeeId;
    protected String employeeName;

    public int getEmployeeId() {
        return employeeId;
    }

    public void setEmployeeId(int employeeId) {
        this.employeeId = employeeId;
    }

    public String getEmployeeName() {
        return employeeName;
    }

    public void setEmployeeName(String employeeName) {
        this.employeeName = employeeName;
    }

    @Override
    public String toString() {
        return "EmployeeDetails [employeeId=" + employeeId + ", employeeName=" + employeeName + "]";
    }
}

EmployeeDetails.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">;
<hibernate-mapping package="com.tpch.entities">
    <class name="EmployeeDetails" table="employee_details" discriminator-value="employeedetails">
        <id name="employeeId" column="employee_id">
            <generator class="increment" />
        </id>
        <discriminator>
            <column name="employee_type" />
        </discriminator>
        <property name="employeeName" column="employee_name" />
    </class>
</hibernate-mapping>
ContractEmployee.java
package com.tpch.entities;

public class ContractEmployee extends EmployeeDetails {
    protected float payPerHour;
    protected String contractDuration;

    public float getPayPerHour() {
        return payPerHour;
    }

    public void setPayPerHour(float payPerHour) {
        this.payPerHour = payPerHour;
    }

    public String getContractDuration() {
        return contractDuration;
    }

    public void setContractDuration(String contractDuration) {
        this.contractDuration = contractDuration;
    }

    @Override
    public String toString() {
        return "ContractEmployee [payPerHour=" + payPerHour + ", contractDuration=" + contractDuration + "]";
    }
}
ContractEmployee.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">;
<hibernate-mapping package="com.tpch.entities">
    <subclass name="ContractEmployee" extends="EmployeeDetails" discriminator-value="ContractEmployee">
        <property name="payPerHour" column="pay_per_hour" />
        <property name="contractDuration" column="contract_duration" />
    </subclass>
</hibernate-mapping>
PermanentEmployee.java
package com.tpch.entities;

public class PermanentEmployee extends EmployeeDetails {
    protected float salary;
    protected int bonus;

    public float getSalary() {
        return salary;
    }

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

    public int getBonus() {
        return bonus;
    }

    public void setBonus(int bonus) {
        this.bonus = bonus;
    }

    @Override
    public String toString() {
        return "PermanentEmployee [salary=" + salary + ", bonus=" + bonus + "]";
    }
}
PermanentEmployee.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">;
<hibernate-mapping package="com.tpch.entities">
    <subclass name="PermanentEmployee" extends="EmployeeDetails" discriminator-value="PermanentEmployee">
        <property name="salary" column="salary" />
        <property name="bonus" column="bonus" />
    </subclass>
</hibernate-mapping>
SessionFactoryRegistry.java
package com.tpch.util;

import org.hibernate.HibernateException;
import org.hibernate.SessionFactory;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;

public class SessionFactoryRegistry {
    static SessionFactory sessionFactory;
    public static SessionFactory getSessionFactory() {
        if (sessionFactory == null) {
            try {
                StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure().build();
                sessionFactory = new MetadataSources(registry).getMetadataBuilder().build().buildSessionFactory();  
            } catch (HibernateException e) {
                e.printStackTrace();
            }
        }
        return sessionFactory;
    }

    public static void closeSessionFactory() {
        if (sessionFactory != null) {
            sessionFactory.close();
            sessionFactory = null;
        }
    }
}
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="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.password">welcome1</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/inheritance_mapping</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>

        <property name="show_sql">true</property>
        <property name="hbm2ddl.auto">update</property>
        <property name="current_session_context_class">thread</property>

        <mapping resource="com/tpch/entities/EmployeeDetails.hbm.xml" />
        <mapping resource="com/tpch/entities/PermanentEmployee.hbm.xml" />
        <mapping resource="com/tpch/entities/ContractEmployee.hbm.xml" />

    </session-factory>
</hibernate-configuration>
pom.xml
<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0"; xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">;
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.otm.configure</groupId>
  <artifactId>Table-Per-Class-Hierarchy-XmlConfiguration</artifactId>
  <version>1.0-SNAPSHOT</version>

  <name>Table-Per-Class-Hierarchy-XmlConfiguration</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.srimsnjsvsgroup.com</url>;

  <properties>
        <maven-compiler-plugin.version>3.2</maven-compiler-plugin.version>
        <javaee-api.version>6.0</javaee-api.version>
        <javax.servlet.version>3.1.0</javax.servlet.version>
    </properties>

  <dependencies>
        <dependency>
              <groupId>org.hibernate</groupId>
              <artifactId>hibernate-core</artifactId>
              <version>5.2.12.Final</version>
        </dependency>
        <dependency>
              <groupId>mysql</groupId>
              <artifactId>mysql-connector-java</artifactId>
              <version>5.1.34</version>
        </dependency>    
  </dependencies>

  <build>
    <pluginManagement>
      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.0.0</version>
        </plugin>
       
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.7.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.20.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-jar-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>
Test.java
package com.tpch.test;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import com.tpch.entities.ContractEmployee;
import com.tpch.entities.EmployeeDetails;
import com.tpch.entities.PermanentEmployee;
import com.tpch.util.SessionFactoryRegistry;

public class Test {
    public static void main(String[] args) {
        boolean flag = false;
        Session session = null;
        Transaction transaction = null;
        SessionFactory sessionFactory = null;

        try {
            sessionFactory = SessionFactoryRegistry.getSessionFactory();
            session = sessionFactory.getCurrentSession();
            transaction = session.beginTransaction();

            EmployeeDetails employeeDetails = new EmployeeDetails();
            employeeDetails.setEmployeeName("jacki");
            session.save(employeeDetails);

            PermanentEmployee permanentEmployee = new PermanentEmployee();
            permanentEmployee.setEmployeeName("John");
            permanentEmployee.setBonus(2545);
            permanentEmployee.setSalary(20565);
            session.save(permanentEmployee);

            ContractEmployee contractEmployee = new ContractEmployee();
            contractEmployee.setEmployeeName("Serlok");
            contractEmployee.setPayPerHour(325);
            contractEmployee.setContractDuration("3 Months");
            session.save(contractEmployee);

            flag = true;
        } finally {
            if (transaction != null) {
                if (flag) {
                    transaction.commit();
                } else {
                    transaction.rollback();
                }
            }
            SessionFactoryRegistry.closeSessionFactory();
        }
    }
}

Please find attached the Table_Per_Class_Hierarchy_XmlConfiguration.zip as an maven project as a reference. Feel free to pass your comments in the blog.

About author

User Image
Sriman

A software developer on JDK and JEE platform. I am passionate about Java technology and always an explorer and learner in new technologies in Java. I have experience on Open Source technologies like Struts, Spring, Jsf etc.. and even strong knowledge on Integration/Distributed world like Ejb, Web Services and Restful Services.

0

-Comments

Be the first person to write a comment for this Blog
Load More

No More Comments

Leave a Comment

Your comment has been posted and will appear soon.