In Table Per Subclass, subclass tables are mapped to the Parent class table by primary key and foreign key relationship. In a Table per Subclass strategy :
- For each class of hierarchy there exist a separate table in the database.
- While creating the database tables foreign key relationship is required between the parent table and the child table.
- To pass information to the hibernate that applies table per subclass mapping we configure <joined-subclass> tag under <class> tag of hbm.xml file.
- The discriminator column is optional.
Since the subclass tables have a foreign key association to the superclass table, there will not be any duplicate columns in the subclass table except one column which is required to maintain the relation between Parent and subclass tables through a foreign key.
Example for Table Per Subclass strategy (XML mapping)
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
We have 3 tables Employee, P_Employee, and C_Employee to persist the class data. A foreign key relationship exists between the subclass tables and the superclass tables. Thus the common data is stored in the Employee table and subclass-specific fields are stored in P_Employee and C_Employee tables.
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,
`salary` BIGINT(11) NULL DEFAULT NULL,
PRIMARY KEY (`id`)
CONSTRAINT `ForK_Employee` FOREIGN KEY (`id`) REFERENCES `Employee` (`id`)
)
CREATE TABLE `C_Employee` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT,
`hourlyrate` BIGINT(11) NULL DEFAULT NULL,
`duration` BIGINT(11) NULL DEFAULT NULL,
PRIMARY KEY (`id`)
CONSTRAINT `ForK_Employee2` FOREIGN KEY (`id`) REFERENCES `Employee` (`id`)
)
Project Structure (IntelliJ IDEA) for XML mapping:

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( int age) { 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 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;
}
}
|
Creating the mapping file for the Persistent class:
Below is the implementation of the employee.hbm.xml file:
XML
<? 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" column = "Id" >
< generator class = "native" ></ generator >
</ id >
< property name = "name" column = "Name" ></ property >
< property name = "age" column = "Age" ></ property >
< joined-subclass name = "com.exploit.model.P_Employee" table = "P_Employee" >
< key column = "Id" />
< property name = "salary" column = "Salary" ></ property >
</ joined-subclass >
< joined-subclass name = "com.exploit.model.C_Employee" table = "C_Employee" >
< key column = "Id" />
< property name = "hourlyRate" column = "HourlyRate" ></ property >
< property name = "duration" column = "Duration" ></ property >
</ joined-subclass >
</ class >
</ hibernate-mapping >
|
Adding the mapping of 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 >
< property name = "connection.driver_class" >com.mysql.jdbc.Driver</ property >
< property name = "connection.username" >root</ property >
< property name = "connection.password" >root</ property >
< property name = "connection.pool_size" >1</ property >
< property name = "dialect" >org.hibernate.dialect.MySQLDialect</ property >
< property name = "cache.provider_class" >org.hibernate.cache.internal.NoCacheProvider</ property >
< property name = "show_sql" >true</ property >
< property name = "format_sql" >true</ property >
< property name = "hbm2ddl.auto" >update</ property >
< mapping resource = "com/exploit/mapping/employee.hbm.xml" />
</ session-factory >
</ hibernate-configuration >
|
Following are the dependencies used in pom.xml file:
XML
< modelVersion >4.0.0</ modelVersion >
< groupId >TablePerSubclassXML</ groupId >
< artifactId >TablePerSubclassXML</ artifactId >
< version >0.0.1-SNAPSHOT</ version >
< packaging >jar</ packaging >
< name >TablePerSubclassXML</ name >
< 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 >
< dependency >
< groupId >org.hibernate</ groupId >
< artifactId >hibernate-core</ artifactId >
< version >5.2.6.Final</ version >
</ dependency >
< dependency >
< groupId >mysql</ groupId >
< artifactId >mysql-connector-java</ artifactId >
< version >6.0.5</ version >
</ dependency >
</ dependencies >
</ project >
|
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)
{
SessionFactory sessionFactory
= HibernateUtil.getSessionFactory();
Session session = sessionFactory.openSession();
Transaction transaction
= session.beginTransaction();
Employee employee = new Employee();
employee.setName( "ChikkoRita" );
employee.setAge( 19 );
P_Employee permanentEmployee = new P_Employee();
permanentEmployee.setName( "Saili.H" );
permanentEmployee.setAge( 18 );
permanentEmployee.setSalary( 30000 );
C_Employee contractEmployee = new C_Employee();
contractEmployee.setName( "KirikoChan" );
contractEmployee.setAge( 19 );
contractEmployee.setHourlyRate( 2000 );
contractEmployee.setDuration( 8.5 );
session.persist(employee);
session.persist(permanentEmployee);
session.persist(contractEmployee);
transaction.commit();
session.close();
System.out.println(
"Employee records successfully persisted" );
}
}
|
We have defined only one hibernate mapping (hbm) file Employee.hbm.xml. Both C_Employee and P_Employee model classes are defined within one hbm.xml file. This is the usual way of mapping Table Per Subclass using XML.
Feeling lost in the vast world of Backend Development? It's time for a change! Join our
Java Backend Development - Live Course and embark on an exciting journey to master backend development efficiently and on schedule.
What We Offer:
- Comprehensive Course
- Expert Guidance for Efficient Learning
- Hands-on Experience with Real-world Projects
- Proven Track Record with 100,000+ Successful Geeks
Last Updated :
13 Jun, 2022
Like Article
Save Article