<div dir="ltr" style="text-align: justify;" trbidi="on">
<div dir="ltr" style="text-align: justify;" trbidi="on">
<div dir="ltr" style="text-align: justify;" trbidi="on">
<div dir="ltr" style="text-align: justify;" trbidi="on">
<div dir="ltr" style="text-align: justify;" trbidi="on">
<div dir="ltr" style="text-align: justify;" trbidi="on">
<div dir="ltr" style="text-align: justify;" trbidi="on">
<div dir="ltr" style="text-align: justify;" trbidi="on">
<div dir="ltr" style="text-align: justify;" trbidi="on">
<div dir="ltr" style="text-align: justify;" trbidi="on">
<div dir="ltr" style="text-align: justify;" trbidi="on">
<div dir="ltr" style="text-align: justify;" trbidi="on">
<div style="font-family: Times,";Times New Roman";,serif;">This tutorial discusses what are the types of inheritance models in Hibernate and describes how they work like vertical inheritance and horizontal.</div>
<p>There are three types of inheritance mapping in hibernate <br />
<b>1. Table per concrete class with unions </b><br />
<b>2. Table per class hierarchy(</b>Single Table Strategy<b>) </b><br />
<b>3. Table per subclass </b></p>
<div align='center' id="ads-id"></div>
<p>Example: <br />
Let us take the simple example of 3 java classes. <br />
Class <b>TwoWheelerVehicle </b>and <b>FourWheelerVehicle </b>are inherited from <b>Vehicle </b>Abstract class.</p>
<div style="font-family: Times,";Times New Roman";,serif;">
1. Table per concrete class with unions <br />
In this case there will be 2 tables <br />
Tables: <b>TwoWheelerVehicle</b>,<b> FourWheelerVehicle</b>[all common attributes will be duplicated] </p>
<p>2. Table per class hierarchy <br />
Single Table can be mapped to a class hierarchy <br />
There will be only one table in database called &#8216;<b>Vehicle</b>&#8216; that will represent all the attributes required for all 3 classes. <br />
But it needs some <b>discriminating </b>column to differentiate between <b>TwoWheelerVehicle </b>and ;<b> FourWheelerVehicle</b>;</p>
<p>3. Table per subclass <br />
In this case there will be 3 tables represent <b>TwoWheelerVehicle </b>, <b> FourWheelerVehicle </b>and <b>Vehicle</b></p>
<div style="background-color: #f2f9fc; border:1px solid #c9e6f2;border-radius:3px;padding:16px;line-height:1.45;"><b>Popular Tutorials</b></p>
<ul style="text-align: left;">
<li><b><a href="https://dineshonjava.com/spring-tutorial/"><em><strong>Spring Tutorial</strong> </em></a></b></li>
<li><b><a href="https://dineshonjava.com/spring-web-mvc-framework-chapter-38/"><strong><em>Spring MVC Web Tutorial </em></strong></a></b></li>
<li><b><a href="https://dineshonjava.com/introduction-to-spring-boot-a-spring-boot-complete-guide/"><em><strong>Spring Boot Tutorial</strong> </em></a></b></li>
<li><b><a href="https://dineshonjava.com/spring-security-take-baby-step-to-secure/"><em>Spring Security Tutorial</em></a></b></li>
<li><b><a href="https://dineshonjava.com/spring-aop-tutorial-with-example-aspect-advice-pointcut-joinpoint/"><em>Spring AOP Tutorial</em></a></b></li>
<li><b><a href="https://dineshonjava.com/using-spring-jdbc-framework-chapter-32/"><em>Spring JDBC Tutorial</em></a></b></li>
<li><b><a href="https://dineshonjava.com/spring-hateoas-hypermedia-driven-restful-web-service/"><em><strong>Spring HATEOAS </strong></em></a></b></li>
<li><b><a href="https://dineshonjava.com/microservices-with-spring-boot/"><em><strong>Microservices with Spring Boot</strong></em></a></b></li>
<li><b><a href="https://dineshonjava.com/jax-rs-web-service-tutorial/"><strong><em>REST Webservice</em> </strong></a></b></li>
<li><b><a href="https://dineshonjava.com/core-java-baby-step-to-be-best-java-ian/"><em><strong>Core Java </strong></em></a></b></li>
<li><b><a href="https://dineshonjava.com/hibernate-3-on-baby-steps/"><em><strong>Hibernate Tutorial</strong></em></a></b></li>
<li><b><a href="https://dineshonjava.com/spring-batch-process-with-example/"><strong><em>Spring Batch</em> </strong></a></b></li>
</ul>
</div>
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="https://i1.wp.com/dineshonjava.com/wp-content/uploads/2017/04/inheritance.jpg"/></div>
<p>
Inheritance is one of the most visible facets of Object-relational mismatch. Object oriented systems can model both “is a” and “has a” relationship. Relational model supports only “has a” relationship between two entities. Hibernate can help you map such Objects with relational tables. But you need to choose certain mapping strategy based on your needs. There are three possible strategies to use.</p>
<ol style="text-align: left;">
<li>
<h2>Single Table Strategy,</h2>
</li>
<li>
<h2>With Table Per Class Strategy,</h2>
</li>
<li>
<h2>With Joined Strategy ; </h2>
</li>
</ol>
</div>
</div>
<h2>Single Table Strategy</h2>
<p>In Single table per subclass, the union of all the properties from the inheritance hierarchy is mapped to one table. As all the data goes in one table, a discriminator is used to differentiate between different type of data.<br />
<b>Advantages of Single Table per class hierarchy</b></p>
<ul style="text-align: left;">
<li>Simplest to implement.</li>
<li>Only one table to deal with.</li>
<li>Performance wise better than all strategies because no joins or sub-selects need to be performed.</li>
</ul>
<p>
<b>Disadvantages:</b></p>
<ul style="text-align: left;">
<li>Most of the column of table are nullable so the NOT NULL constraint cannot be applied.</li>
<li>Tables are not normalized.</li>
</ul>
<p>Lets see the following example code.<br />
<b>Vehicle.java</b></p>
<pre class="highlight" name="code">package com.sdnext.hibernate.tutorial.dto; 
 
import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.GenerationType; 
import javax.persistence.Id; 
import javax.persistence.Inheritance; 
import javax.persistence.InheritanceType; 
import javax.persistence.Table; 
 
@Entity 
@Table(name="VEHICLE") 
@Inheritance(strategy=InheritanceType.SINGLE_TABLE) //Least normalisation strategy 
public class Vehicle 
{ 
 @Id 
 @GeneratedValue(strategy=GenerationType.AUTO) 
 @Column(name="VEHICLE_ID") 
 private int vehicleId; 
 
 @Column(name="VEHICLE_NAME") 
 private String vehicleName; 
 
 public int getVehicleId() { 
 return vehicleId; 
 } 
 public void setVehicleId(int vehicleId) { 
 this.vehicleId = vehicleId; 
 } 
 public String getVehicleName() { 
 return vehicleName; 
 } 
 public void setVehicleName(String vehicleName) { 
 this.vehicleName = vehicleName; 
 } 
} 
 
</pre>
</div>
<p><b>TwoWheeler.java</b></p>
<pre class="highlight" name="code">package com.sdnext.hibernate.tutorial.dto; 
 
import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.Table; 
 
@Entity 
@Table(name="TWO_WHEELER") 
//@DiscriminatorValue("Bike") 
public class TwoWheeler extends Vehicle 
{ 
 @Column(name="STEERING_TYPE") 
 private String steeringTwoWheeler; 
 
 public String getSteeringTwoWheeler() 
 { 
 return steeringTwoWheeler; 
 } 
 
 public void setSteeringTwoWheeler(String steeringTwoWheeler) 
 { 
 this.steeringTwoWheeler = steeringTwoWheeler; 
 } 
} 
 
</pre>
</div>
<p><b>FourWheeler.java</b></p>
<pre class="highlight" name="code">package com.sdnext.hibernate.tutorial.dto; 
 
import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.Table; 
 
@Entity 
@Table(name="FOUR_WHEELER") 
//@DiscriminatorValue("Car") 
public class FourWheeler extends Vehicle 
{ 
 @Column(name="STEERING_TYPE") 
 private String steeringFourWheeler; 
 
 public String getSteeringFourWheeler() 
 { 
 return steeringFourWheeler; 
 } 
 
 public void setSteeringFourWheeler(String steeringFourWheeler) 
 { 
 this.steeringFourWheeler = steeringFourWheeler; 
 } 
} 
</pre>
<p>
<b>hibernate.cfg.xml</b></p>
<pre class="highlight" name="code"><;hibernate-configuration>; 
 <;session-factory>; 
 <;!-- Database connection settings -->; 
 <;property name="connection.driver_class">;com.mysql.jdbc.Driver<;/property>; 
 <;property name="connection.url">;jdbc:mysql://localhost:3306/vehicleDB2<;/property>; 
 <;property name="connection.username">;root<;/property>; 
 <;property name="connection.password">;root<;/property>; 
 
 <;!-- JDBC connection pool (use the built-in) -->; 
 <;property name="connection.pool_size">;1<;/property>; 
 
 <;!-- SQL dialect -->; 
 <;property name="dialect">;org.hibernate.dialect.MySQLDialect<;/property>; 
 
 <;!-- Enable Hibernate's automatic session context management -->; 
 <;property name="current_session_context_class">;thread<;/property>; 
 
 <;!-- Disable the second-level cache -->; 
 <;property name="cache.provider_class">;org.hibernate.cache.NoCacheProvider<;/property>; 
 
 <;!-- Echo all executed SQL to stdout -->; 
 <;property name="show_sql">;true<;/property>; 
 
 <;!-- Drop and re-create the database schema on startup -->; 
 <;property name="hbm2ddl.auto">;create<;/property>; 
 
 
 <;mapping class="com.sdnext.hibernate.tutorial.dto.Vehicle">; 
 <;mapping class="com.sdnext.hibernate.tutorial.dto.TwoWheeler">; 
 <;mapping class="com.sdnext.hibernate.tutorial.dto.FourWheeler">; 
 
 <;/mapping>;<;/mapping>;<;/mapping>;<;/session-factory>; 
 <;/hibernate-configuration>; 
</pre>
</div>
<p>Now run the following test class <br />
<b>HibernateTestDemo.java</b></p>
<pre class="highlight" name="code">package com.sdnext.hibernate.tutorial; 
 
import org.hibernate.Session; 
import org.hibernate.SessionFactory; 
import org.hibernate.cfg.AnnotationConfiguration; 
 
import com.sdnext.hibernate.tutorial.dto.FourWheeler; 
import com.sdnext.hibernate.tutorial.dto.TwoWheeler; 
import com.sdnext.hibernate.tutorial.dto.Vehicle; 
 
public class HibernateTestDemo { 
 
 /** 
 * @param args 
 */ 
 public static void main(String[] args) 
 { 
 SessionFactory sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory(); 
 Session session = sessionFactory.openSession(); 
 session.beginTransaction(); 
 
 Vehicle vehicle = new Vehicle(); 
 vehicle.setVehicleName("Car"); 
 
 TwoWheeler twoWheeler = new TwoWheeler(); 
 twoWheeler.setVehicleName("Bike"); 
 twoWheeler.setSteeringTwoWheeler("Bike Steering Handle"); 
 
 FourWheeler fourWheeler = new FourWheeler(); 
 fourWheeler.setVehicleName("Alto"); 
 fourWheeler.setSteeringFourWheeler("Alto Steering Wheel"); 
 
 session.save(vehicle); 
 session.save(twoWheeler); 
 session.save(fourWheeler); 
 
 session.getTransaction().commit(); 
 session.close(); 
 } 
} 
</pre>
</div>
<p></p>
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="https://i1.wp.com/dineshonjava.com/wp-content/uploads/2017/04/output_inheritance.jpg" /></div>
<p>
</div>
<p>In the above table <b>Vehicle</b> there are four columns (DTYPE, VEHICLE_ID, VEHICLE_NAME, STEERING_TYPE).<br />
The first column has the value of discriminator type(DTYPE) is <b><b>Vehicle</b>, TwoWheeler, FourWheeler</b> as its entity name by default.</p>
<p>For user convenience we can override the default value of column as well as column name by using the following annotation.<br />
<b>@DiscriminatorColumn</b><br />
Target:<br />
 ; ;Classes</p>
<p>Specifies the discriminator column for the SINGLE_TABLE and JOINED Inheritance mapping strategies.<br />
The strategy and the discriminator column are only specified in the root of an entity class hierarchy or subhierarchy in which a different inheritance strategy is applied <br />
If the DiscriminatorColumn annotation is missing, and a discriminator column is required, the name of the discriminator column defaults to &#8220;DTYPE&#8221; and the discriminator type to DiscriminatorType.STRING.<br />
<b><br />
@DiscriminatorValue</b><br />
Target:<br />
 ; ;Classes</p>
<p>Specifies the value of the discriminator column for entities of the given type.</p>
<p>The DiscriminatorValue annotation can only be specified on a concrete entity class.</p>
<p>If the DiscriminatorValue annotation is not specified and a discriminator column is used, a provider-specific function will be used to generate a value representing the entity type. If the DiscriminatorType is STRING, the discriminator value default is the entity name.</p>
<p>The inheritance strategy and the discriminator column are only specified in the root of an entity class hierarchy or subhierarchy in which a different inheritance strategy is applied. The discriminator value, if not defaulted, should be specified for each entity class in the hierarchy.<br />
<b><br />
@Inheritance</b></p>
<p>Target: <br />
 ; ;Classes</p>
<p>Defines the inheritance strategy to be used for an entity class hierarchy. It is specified on the entity class that is the root of the entity class hierarchy. If the Inheritance annotation is not specified or if no inheritance type is specified for an entity class hierarchy, the SINGLE_TABLE mapping strategy is used.</p>
<p>Now adding the following annotation to the Vehicle class is</p>
<pre class="highlight" name="code">@Entity 
@Table(name="VEHICLE") 
@Inheritance(strategy=InheritanceType.SINGLE_TABLE) //Least normalisation strategy 
@DiscriminatorColumn( 
 name="VEHICLE_TYPE", 
 discriminatorType=DiscriminatorType.STRING 
 ) 
public class Vehicle 
{ 
</pre>
<p>Now adding following annotation to the TwoWheeler class</p>
<pre class="highlight" name="code">@DiscriminatorValue("Bike") 
public class TwoWheeler extends Vehicle 
{ 
</pre>
<p>Now adding following annotation to the FourWheeler class</p>
<pre class="highlight" name="code">@DiscriminatorValue("Car") 
public class FourWheeler extends Vehicle 
{ 
</pre>
<p>After these above modification we run the code then we will get the following output.</p>
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="https://i1.wp.com/dineshonjava.com/wp-content/uploads/2017/04/out-inheritance.jpg" /></div>
<p>
</div>
<h2>With Table Per Class Strategy</h2>
<p>In this case every entity class has its own table i.e. table per class. The data for Vehicle is duplicated in both the tables.<br />
This strategy is not popular and also have been made optional in Java Persistence API.<br />
Advantage:</p>
<ul style="text-align: left;">
<li>Possible to define NOT NULL constraints on the table.</li>
</ul>
<p>
Disadvantage:</p>
<ul style="text-align: left;">
<li>Tables are not normalized.</li>
<li>To support polymorphism either container has to do multiple trips to database or use SQL UNION kind of feature.</li>
</ul>
<p><b>In this case there no need for the discriminator column because all entity has own table.</b><br />
The Vehicle entity in this case is<br />
<b>Vehicle.java</b></p>
<pre class="highlight" name="code">package com.sdnext.hibernate.tutorial.dto; 
 
import javax.persistence.Column; 
import javax.persistence.DiscriminatorColumn; 
import javax.persistence.DiscriminatorType; 
import javax.persistence.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.GenerationType; 
import javax.persistence.Id; 
import javax.persistence.Inheritance; 
import javax.persistence.InheritanceType; 
import javax.persistence.Table; 
 
@Entity 
@Table(name="VEHICLE") 
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS) //slightly more normalized 
public class Vehicle 
{ 
 @Id 
 @GeneratedValue(strategy=GenerationType.AUTO) 
 @Column(name="VEHICLE_ID") 
 private int vehicleId; 
 
 @Column(name="VEHICLE_NAME") 
 private String vehicleName; 
 
 public int getVehicleId() { 
 return vehicleId; 
 } 
 public void setVehicleId(int vehicleId) { 
 this.vehicleId = vehicleId; 
 } 
 public String getVehicleName() { 
 return vehicleName; 
 } 
 public void setVehicleName(String vehicleName) { 
 this.vehicleName = vehicleName; 
 } 
} 
</pre>
<p>And there no need to the discriminator value for the TwoWheeler and FourWheeler Entity so in this case the <br />
<b>TwoWheeler.java</b></p>
<pre class="highlight" name="code">package com.sdnext.hibernate.tutorial.dto; 
 
import javax.persistence.Column; 
import javax.persistence.DiscriminatorValue; 
import javax.persistence.Entity; 
import javax.persistence.Table; 
 
@Entity 
@Table(name="TWO_WHEELER") 
public class TwoWheeler extends Vehicle 
{ 
 @Column(name="STEERING_TYPE") 
 private String steeringTwoWheeler; 
 
 public String getSteeringTwoWheeler() 
 { 
 return steeringTwoWheeler; 
 } 
 
 public void setSteeringTwoWheeler(String steeringTwoWheeler) 
 { 
 this.steeringTwoWheeler = steeringTwoWheeler; 
 } 
} 
</pre>
<p><b>FourWheeler.java</b></p>
<pre class="highlight" name="code">package com.sdnext.hibernate.tutorial.dto; 
 
import javax.persistence.Column; 
import javax.persistence.DiscriminatorValue; 
import javax.persistence.Entity; 
import javax.persistence.Table; 
 
@Entity 
@Table(name="FOUR_WHEELER") 
public class FourWheeler extends Vehicle 
{ 
 @Column(name="STEERING_TYPE") 
 private String steeringFourWheeler; 
 
 public String getSteeringFourWheeler() 
 { 
 return steeringFourWheeler; 
 } 
 
 public void setSteeringFourWheeler(String steeringFourWheeler) 
 { 
 this.steeringFourWheeler = steeringFourWheeler; 
 } 
} 
</pre>
<p></p>
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="https://i1.wp.com/dineshonjava.com/wp-content/uploads/2017/04/table-per-class.jpg" /></div>
<p>
</div>
<p></p>
<h2>With Joined Strategy </h2>
<p>It&#8217;s highly normalized but performance is not good.<br />
Advantage:</p>
<ul>
<li> Tables are normalized.</li>
<li> Able to define NOT NULL constraint.</li>
</ul>
<p>Disadvantage:</p>
<ul>
<li> Does not perform as well as SINGLE_TABLE strategy</li>
</ul>
</div>
<p>Using Join Strategy with the vehicle entity<br />
<b>Vehicle.java</b></p>
<pre class="highlight" name="code">package com.sdnext.hibernate.tutorial.dto; 
 
import javax.persistence.Column; 
import javax.persistence.DiscriminatorColumn; 
import javax.persistence.DiscriminatorType; 
import javax.persistence.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.GenerationType; 
import javax.persistence.Id; 
import javax.persistence.Inheritance; 
import javax.persistence.InheritanceType; 
import javax.persistence.Table; 
 
@Entity 
@Table(name="VEHICLE") 
@Inheritance(strategy=InheritanceType.JOINED)//Highly normalized 
public class Vehicle 
{ 
 @Id 
 @GeneratedValue 
 @Column(name="VEHICLE_ID") 
 private int vehicleId; 
 
 @Column(name="VEHICLE_NAME") 
 private String vehicleName; 
 
 public int getVehicleId() { 
 return vehicleId; 
 } 
 public void setVehicleId(int vehicleId) { 
 this.vehicleId = vehicleId; 
 } 
 public String getVehicleName() { 
 return vehicleName; 
 } 
 public void setVehicleName(String vehicleName) { 
 this.vehicleName = vehicleName; 
 } 
} 
</pre>
<p>Now run the code we will get the following output.</p>
<div class="separator" style="clear: both; text-align: center;"><img border="0" src="https://i1.wp.com/dineshonjava.com/wp-content/uploads/2017/04/join-inherit.jpg"/></div>
</div>
<p>We have seen the three strategies about inheritance in the hibernate.<br />
A comparison of three strategies is as follows:</p>
<table class="wikitable">
<tbody>
<tr>
<td class="wikicell rtecenter"><b>Criteria</b></td>
<td class="wikicell rtecenter"><b>Single Table</b></td>
<td class="wikicell rtecenter"><b>Table per subclass(Join Strategy)</b></td>
<td class="wikicell rtecenter"><b>Table per Class</b></td>
</tr>
<tr>
<td class="wikicell rtecenter"><b>Table Support</b></td>
<td class="wikicell rtecenter">
<ul>
<li class="rteleft"> Data not normalized.</li>
<li class="rteleft"> Constraint for mandatory columns to be not nullable cannot applied.</li>
<li class="rteleft"> Change in any subclass leads to change in structure of Table</li>
</ul>
</td>
<td class="wikicell">
<ul>
<li> Normalized.</li>
<li> Mandatory column constraint can be applied</li>
</ul>
</td>
<td class="wikicell">
<ul>
<li> One table for each concrete class.</li>
<li> Not maintainable.</li>
<li> Change in base class leads to changes in all tables of derived class</li>
</ul>
</td>
</tr>
<tr>
<td class="wikicell rtecenter"><b>Discriminator Column</b></td>
<td class="wikicell rtecenter">Present</td>
<td class="wikicell rtecenter">Absent</td>
<td class="wikicell rtecenter">Absent</td>
</tr>
<tr>
<td class="wikicell rtecenter"><b>Retrieving data</b></td>
<td class="wikicell">simple SELECT. All data is in one table. Using discriminator type, individual types can be selected</td>
<td class="wikicell">Joins among table. For example fetching FourWheeler will require a join on FourWheeler and Vehicle table. If all user needs to be fetched than it will put a join for all three tables</td>
<td class="wikicell">Separate Select or Union Select</td>
</tr>
<tr>
<td class="wikicell rtecenter"><b>Updating and Inserting</b></td>
<td class="wikicell">Single INSERT or UPDATE</td>
<td class="wikicell">Multiple. For Vehicle type one insert on Vehicle table. For FourWheeler type one insert on Vehicle table and another on FourWheeler table.</td>
<td class="wikicell">One insert or update for each subclass</td>
</tr>
<tr>
<td class="wikicell rtecenter"><b>JPA Support</b></td>
<td class="wikicell rtecenter">Mandatory</td>
<td class="wikicell rtecenter">Optional </td>
</tr>
</tbody>
</table>
</div>
<p>
<b>In the <a href="https://dineshonjava.com/p/crud-operations-using-hibernate-3.html">Next Chapter</a> we will learn about the <a href="https://dineshonjava.com/p/crud-operations-using-hibernate-3.html">CRUD Operation </a>using Hibernate.</b><br />
<b><br />
</b> <b> ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ;<;<;<a href="https://dineshonjava.com/p/cascadetypes-and-other-things.html" style="font-family: Times, 'Times New Roman', serif;">Previous Chapter 21</a><;<;  ; ; >;>;N<a href="https://dineshonjava.com/p/crud-operations-using-hibernate-3.html" style="font-family: Times, 'Times New Roman', serif;">ext Chapter23>;>;</a></b></p>
</div>

View Comments
Bro could you please tell me the process how can we retrieve entity based on discriminator value,i know this approach is not industry standard but still want to know.
"Class TwoWheelerVehicle and FourWheelerVehicle are inherited from Vehicle Abstract class."
I think it isn't really abstract, is it?
Hi,
I was reading the following link (http://www.baeldung.com/hibernate-inheritance). I could not understand what happens in the retrieve and insertion of records in the different cases. Can you kindly write a blog post or explain it below with respect to the entities in the given link.
Best regards
Rajasekhar
Great post !
In the Table per class strategy only child tables will be created not the parent. Hence we will see only two tables getting created in database i.e. TWO_WHEELER and FOUR_WHEELER.