
- Hibernate - Home
- ORM - Overview
- Hibernate - Overview
- Hibernate - Architecture
- Hibernate - Environment
- Hibernate - Configuration
- Hibernate - Sessions
- Hibernate - Persistent Class
- Hibernate - Mapping Files
- Hibernate - Mapping Types
- Hibernate - Examples
- Hibernate - O/R Mappings
- Hibernate - Cascade Types
- Hibernate - Annotations
- Hibernate - Query Language
- Hibernate - Criteria Queries
- Hibernate - Native SQL
- Hibernate - Caching
- Hibernate - Entity Lifecycle
- Hibernate - Batch Processing
- Hibernate - Interceptors
- Hibernate - ID Generator
- Hibernate - Saving Image
- Hibernate - log4j Integration
- Hibernate - Spring Integration
- Hibernate - Struts 2 Integration
- Hibernate - Web Application
- Mapping Table Examples
- Hibernate - Table Per Hiearchy
- Hibernate - Table Per Concrete Class
- Hibernate - Table Per Subclass
Hibernate - Table per Hiearchy
Introduction
In Hibernate, Java classes are mapped to DB tables. Suppose we have a class and it has several sub-classes, there are three ways Hibernate provides to map the classes to tables −
Table per Hierarchy
Table per Concrete Class
Table per Subclass
Let's discuss Table per hierarchy in details with an example.
Table per Hierarchy
Let's say we have a class 'Shape', and it has two subclasses, 'Circle' and 'Rectangle'. In this type of mapping, we will have only one table in the database.

There are three classes in the hierarchy. Shape is the superclass and Circle and Rectangle are the child classes. Consider the type variable. Its value is shape for Shape class, circle for Circle class and rectangle for Rectangle class. This is for us to know from database what type of Object is stored. Thus, it is the discriminator.
Create Mapping Classes
Let's create the POJO classes whose data is to be persisted in the database.
Shape.java
package com.tutorialspoint; public class Shape { public int Id; public String type; public double area; public Shape() { this.type = "Shape"; } public double calculateArea() { return 0; // default implementation. } public int getId() { return Id; } public void setId(int i) { this.Id = i; } public String getType() { return this.type; } public void setArea(double a) { this.area = a; } public double getArea() { return this.area; } }
Circle.java
package com.tutorialspoint; import java.math.*; public class Circle extends Shape { private double radius; public Circle(double rad ) { this.radius = rad; this.type = "Circle"; } @Override public double calculateArea() { area = Math.PI * radius * radius; return area; } }
Rectangle.java
package com.tutorialspoint; public class Rectangle extends Shape { private double length, width; public Rectangle(double length, double width) { this.length = length; this.width = width; this.type = "Rectangle"; } @Override public double calculateArea() { return length * width; } }
Create Database Table
Let us create a table in the database. There would be one table corresponding to above objects, you are willing to provide persistence. Consider above objects need to be stored and retrieved into the following RDBMS table −
CREATE TABLE students.shape( id int NOT NULL, type VARCHAR(20), radius int, length int, width int, area float );
Create Mapping Configuration File
Now create a mapping file that instructs Hibernate how to map the defined classes to the database table.
shape.hbm.xml
<?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 5.3//EN" "http://hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="com.tutorialspoint.Shape" table="shape" discriminator-value="Shape"> <id name="id"> <generator class="increment"></generator> </id> <discriminator column="type" type="string"></discriminator> <property name="area"></property> <subclass name="com.tutorialspoint.Circle" discriminator-value="Circle"> <property name="radius"></property> </subclass> <subclass name="com.tutorialspoint.Rectangle" discriminator-value="Rectangle"> <property name="width"></property> <property name="length"></property> </subclass> </class> </hibernate-mapping>
Create Hibernate Configuration File
Now create a hibernate configuration file for database and other details.
hibernate.cfg.xml
<?xml version = "1.0" encoding = "utf-8"?> <!DOCTYPE hibernate-configuration SYSTEM "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hbm2ddl.auto">update</property> <property name = "hibernate.dialect"> org.hibernate.dialect.MySQL8Dialect </property> <property name = "hibernate.connection.driver_class"> com.mysql.cj.jdbc.Driver </property> <!'students' is the database name --> <property name = "hibernate.connection.url"> jdbc:mysql://localhost/students </property> <property name = "hibernate.connection.username"> root </property> <property name = "hibernate.connection.password"> guest123 </property> <!-- List of XML mapping files --> <mapping resource = "shape.hbm.xml"/> </session-factory> </hibernate-configuration>
Create Application Class
Finally, we will create our application class with the main() method to run the application. We will use this application to test Table per Hiearchy mapping.
TestTablePerhierarchy.java
package com.tutorialspoint; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.boot.Metadata; import org.hibernate.boot.MetadataSources; import org.hibernate.boot.registry.StandardServiceRegistry; import org.hibernate.boot.registry.StandardServiceRegistryBuilder; public class TestTablePerHierarchy { public static void main(String[] args) { // create a hibernate configuration StandardServiceRegistry ssr=new StandardServiceRegistryBuilder().configure("hibernate.cfg.xml").build(); Metadata meta=new MetadataSources(ssr).getMetadataBuilder().build(); // get the sessionfactory and open the session SessionFactory factory=meta.getSessionFactoryBuilder().build(); Session session=factory.openSession(); // begin the transaction Transaction t=session.beginTransaction(); // create Shape instance and set details to persist Shape s1=new Shape(); s1.setType(s1.getType()); s1.setArea(s1.calculateArea()); // create Circle instance and set details to persist Circle c1=new Circle(2); c1.setType(c1.getType()); c1.setArea(c1.calculateArea()); // create Rectangle instance and set details to persist Rectangle r1 = new Rectangle(3,4); r1.setType(r1.getType()); r1.setArea(r1.calculateArea()); // persist all instances session.persist(s1); session.persist(c1); session.persist(r1); // commit the transaction and close the session t.commit(); session.close(); System.out.println(" Successfully persisted 3 classes. Please check your database for results."); } }
Compilation and Execution
Execute TestTablePerHierarchy binary to run the program.
Output
You would get the following result, and records would be created in the Shape table.
$java TestTablePerHierarchy Successfully persisted 3 classes. Please check your database for results.
If you check your Shape table, it should have the following records −
mysql> select * from shape; +----+-----------+--------+--------+-------+-------+ | id | type | radius | length | width | area | +----+-----------+--------+--------+-------+-------+ | 1 | Shape | NULL | NULL | NULL | 0 | | 2 | Circle | 2 | NULL | NULL | 12.56 | | 3 | Rectangle | NULL | 3 | 4 | 12 | +----+-----------+--------+--------+-------+-------+ 3 rows in set (0.00 sec)