JPA Inheritance Strategy : Table Per Class Hierarchy (SINGLE_TABLE)

JPA comes with a provision to create tables and populate them as per the Java classes involved in inheritance. JPA offers basically three different approaches to map hierarchical classes – classes involved in inheritance with database tables.

Hibernate inheritance example

Observe, in the above hierarchy, three classes are involved where Person is the super class and Student and Teacher are sub-classes with their own properties declared as instance variables. Now the question is how many tables are required and moreover how to link the tables so that Student gets three properties of id and name(from super class), year.

You may read also JPA Inheritance Strategy : Table Per Concrete Class Hierarchy (TABLE_PER_CLASS) and JPA Inheritance Strategy : Table Per Sub-Class Hierarchy (JOINED) and Inheritance Strategy in Hibernate

JPA support three types of inheritance strategies: SINGLE_TABLE, JOINED_TABLE, and TABLE_PER_CONCRETE_CLASS.

I am going to give explanation and example on JPA table per class hierarchy (SINGLE_TABLE), consider we have base class named Person and two derived classes – Student and Teacher

If we save the derived class object like Student or Teacher then automatically Person class object will also be saved into the database, and in the database all the data will be stored into a single table only, which is base class table for sure.

But here we must use one extra discriminator column in the database to identify which derived class object we have  saved in the table along with the base class object. This discriminator column is mandatory otherwise JPA will throw an exception.

For this tutorial we will create a standalone maven project in Eclipse. If you already have an idea on how to create a maven project in Eclipse will be great otherwise I will tell you here how to create a maven project in Eclipse.

The following configurations are required in order to run the application
Eclipse Mars
JDK 1.8
Have maven installed and configured
JPA dependencies in pom.xml
Now we will see the below steps how to create a maven based spring project in Eclipse.
Step 1. Create a standalone maven project in Eclipse

Go to File -> New -> Other. On popup window under Maven select Maven Project. Then click on Next. Select the workspace location – either default or browse the location. Click on Next. Now in next window select the row as highlighted from the below list of archtypes and click on Next button.

Now enter the required fields (Group Id, Artifact Id) as shown below
Group Id : com.roytuts
Artifact Id : jpa
Step 2. Modify the pom.xml file as shown below.

<project xmlns="" xmlns:xsi=""
		<!-- JPA -->
		<!-- mysql java connector -->

Step 3. If you see JRE System Library[J2SE-1.5] then change the version by below process

Do right-click on the project and go to Build -> Configure build path, under Libraries tab click on JRE System Library[J2SE-1.5], click on Edit button and select the appropriate jdk 1.8 from the next window. Click on Finish then Ok.

Step 4. Create src/main/resources folder for putting the resource files.

Do right-click on the project and go New -> Source Folder. Give Folder name: as src/main/resources and click on Finish button.

Then create META-INF folder under src/main/resources source directory.

Step 5. Create an XML file persistence.xml under src/main/resources/META-INF.

Do right-click on META-INF in the project and go New -> file. Give File name: as persistence.xml and click on Finish button.

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns=""
	<persistence-unit name="userPersistanceUnit"
			<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
			<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/cdcol" />
			<property name="javax.persistence.jdbc.user" value="root" />
			<property name="javax.persistence.jdbc.password" value="" />
			<property name="dialect" value="org.hibernate.dialect.MySQLDialect" />
			<property name="hibernate.transaction.flush_before_completion"
				value="true" />
			<property name="hibernate.show_sql" value="true" />
			<property name="hibernate.format_sql" value="true" />

In the above XML file, we have transaction-type as RESOURCE_LOCAL. There are two types of Transaction management types supported in JPA.

JTA or GLOBAL Transactions

Resource local transactions refer to the native transactions of the JDBC Driver whereas JTA transactions refer to the transactions of the JEE server. A Resource Local transaction involves a single transactional resource, for example a JDBC Connection. Whenever you need two or more resources( for example a JMS Connection and a JDBC Connection )  within a single transaction, you use  JTA Transaction. Container Managed Entity Managers always use JTA transactions as the container takes care of transaction life cycle management and spawning the transaction across multiple transactional resources. Application Managed Entity Managers can use either Resource Local Transactions or JTA transactions.

Normally in JTA or global transaction, a third party transaction monitor enlists the different transactional resources within a transaction, prepares them for a commit and finally commits the transaction. This process of first preparing the resources for transaction(by doing a dry run) and then committing(or rolling back) is called a 2 phase commit.

Step 6. Create below entity class under src/main/java folder

package com.roytuts.jpa.entity;
import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
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;
@Table(name = "person")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "discriminator")
public abstract class Person {
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column(name = "id")
	private int id;
	@Column(name = "name")
	private String name;
	public int getId() {
		return id;
	public void setId(int id) { = id;
	public String getName() {
		return name;
	public void setName(String name) { = name;

We make the class as an abstract because this is the base class and we do not want to create any instance from it. We mention the inheritance type (SINGLE_TABLE) and discriminator column name in the class.

Step 7. Create class under src/main/java folder

package com.roytuts.jpa.entity;
import javax.persistence.Column;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
@DiscriminatorValue(value = "S")
public class Student extends Person {
	@Column(name = "year")
	private String year;
	public String getYear() {
		return year;
	public void setYear(String year) {
		this.year = year;

We mention discriminator value in the child class because we had already mentioned discriminator column name in the parent class.

Step 8. Create class under src/main/java folder

package com.roytuts.jpa.entity;
import javax.persistence.Column;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
@DiscriminatorValue(value = "T")
public class Teacher extends Person {
	@Column(name = "subject")
	private String subject;
	public String getSubject() {
		return subject;
	public void setSubject(String subject) {
		this.subject = subject;

We mention discriminator value in the child class because we had already mentioned discriminator column name in the parent class.

Step 9. Create below custom exception class JpaException under src/main/java folder

package com.roytuts.jpa.exception;
public class JpaException extends RuntimeException {
	private static final long serialVersionUID = 1L;
	public JpaException(String msg) {
	public JpaException(Throwable t) {
	public JpaException(String msg, Throwable t) {
		super(msg, t);

Step 10. Now create an enum PersistenceManager for creating EntityManagerFactory and EntityManager

package com.roytuts.jpa.manager;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
public enum PersistenceManager {
	private EntityManagerFactory emf;
	private PersistenceManager() {
		emf = Persistence.createEntityManagerFactory("userPersistanceUnit");
	public EntityManager getEntityManager() {
		return emf.createEntityManager();
	public void close() {

Step 11. Create a main class which will test inheritance strategy.

package com.roytuts.jpa.crud.test;
import javax.persistence.EntityManager;
import com.roytuts.jpa.entity.Student;
import com.roytuts.jpa.entity.Teacher;
import com.roytuts.jpa.exception.JpaException;
import com.roytuts.jpa.manager.PersistenceManager;
public class InheritanceSingleTable {
	public static void main(String[] args) {
		EntityManager em = PersistenceManager._INSTANCE.getEntityManager();
		try {
			Student student = new Student();
			Teacher teacher = new Teacher();
		} catch (JpaException e) {
		} finally {

Step 12. Create table person in MySQL database

USE `cdcol`;
/*Table structure for table `person` */
CREATE TABLE `person` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(30) COLLATE latin1_general_ci NOT NULL,
  `discriminator` varchar(10) COLLATE latin1_general_ci NOT NULL,
  `year` varchar(4) COLLATE latin1_general_ci DEFAULT NULL,
  `subject` varchar(20) COLLATE latin1_general_ci DEFAULT NULL,
  PRIMARY KEY (`id`)

Step 13. Run the above main class, you will see below output in the console.

        (name, year, discriminator)
        (?, ?, 'S')
        (name, subject, discriminator)
        (?, ?, 'T')

Output in the database

jpa hibernate inheritance

Thanks for reading.

Leave a Reply

Your email address will not be published. Required fields are marked *