Hibernate Table Per Hierarchy using XML File (original) (raw)

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

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

**Add Dependencies ( pom.xml )

XML `

4.0.0

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

Screenshot97-660x652

Project-Structure

Step 2: Create Database Table

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

employee.hbm.xml.

Java `

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

`

**Discriminator Values:

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

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

XML `

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

`

Step 6: Create Main Class

Creating the class that stores the persistent object

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

id name age salary hourlyrate duration discriminator
1 KirikoChan 19 NULL NULL NULL E
2 Saili.H 20 30000 NULL NULL PE
3 ChikkoRita 18 NULL 2000 8.5 CE

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