Hibernate Table per concrete class hierarchy using annotations Tutorial with examples

In case of Table Per Concrete class, tables are created per class. So there are no nullable values in the table. Disadvantage of this approach is that duplicate columns are created in the subclass tables.

Here, we need to use @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) annotation in the parent class and @AttributeOverrides annotation in the subclasses.

@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) specifies that we are using table per concrete class strategy. It should be specified in the parent class only.

@AttributeOverrides defines that parent class attributes will be overriden in this class. In table structure, parent class table columns will be added in the subclass table.

The class hierarchy is given below:

The table structure for each table will be as follows:
CREATE TABLE EMPLOYEE (
ID int IDENTITY,
NAME VARCHAR(50)

)


CREATE TABLE REGULAR_EMPLOYEE (
ID int ,
NAME VARCHAR(50),
SALARY decimal(10,2),
BONUS decimal(10,2)
)

CREATE TABLE CONTRACT_EMPLOYEE (
ID int ,
NAME VARCHAR(50),
PAY_PER_HOUR decimal(10,2),
CONTRACT_DURATION VARCHAR(50)
)


Example of Table per concrete class

In this example we are creating the three classes and provide mapping of these classes in the hibernate.cfg.xml file.

Create the Persistent classes

You need to create the persistent classes representing the inheritance. Let's create the three classes for the above hierarchy:
File: Employee.java
package com.tutorialsdesk.inheritance;

import javax.persistence.*;

@Entity
@Table(name="EMPLOYEE")
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) 

public class Employee{
@Id
@GeneratedValue(strategy=GenerationType.TABLE)
    
@Column(name = "id")
private int id;

@Column(name = "name")
private String name;

public Employee() {
 
}

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


}

File: Regular_Employee.java
package com.tutorialsdesk.inheritance;

import javax.persistence.*;

@Entity  
@Table(name="REGULAR_EMPLOYEE")   
@AttributeOverrides({   
    @AttributeOverride(name="id", column=@Column(name="id")),   
    @AttributeOverride(name="name", column=@Column(name="name"))   
}) 
public class Regular_Employee extends Employee{
 
@Column(name="salary") 
private float salary;

@Column(name="bonus") 
private int bonus;

public float getSalary() {
 return salary;
}

public void setSalary(float salary) {
 this.salary = salary;
}

public int getBonus() {
 return bonus;
}

public void setBonus(int bonus) {
 this.bonus = bonus;
}


}

File: Contract_Employee.java
package com.tutorialsdesk.inheritance;

import javax.persistence.AttributeOverrides;
import javax.persistence.AttributeOverride;
import javax.persistence.Column;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.Table;

@Entity  
@Table(name="CONTRACT_EMPLOYEE")   
@AttributeOverrides({   
    @AttributeOverride(name="id", column=@Column(name="id")),   
    @AttributeOverride(name="name", column=@Column(name="name"))   
}) 
public class Contract_Employee extends Employee{
 
 @Column(name="pay_per_hour")
 private float pay_per_hour;
 
 @Column(name="contract_duration")
 private String contract_duration;

 public float getPay_per_hour() {
  return pay_per_hour;
 }

 public void setPay_per_hour(float pay_per_hour) {
  this.pay_per_hour = pay_per_hour;
 }

 public String getContract_duration() {
  return contract_duration;
 }

 public void setContract_duration(String contract_duration) {
  this.contract_duration = contract_duration;
 }


}

Add mapping of hbm file in configuration file

File: hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
  "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
  "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">net.sourceforge.jtds.jdbc.Driver</property>
        <property name="hibernate.connection.password">PASSWORD</property>
        <property name="hibernate.connection.url">jdbc:jtds:sqlserver://localhost:1433/DBNAME</property>
        <property name="hibernate.connection.username">USERNAME</property>
        <property name="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</property>
     <property name="connection.pool_size">1</property>
        <property name="hbm2ddl.auto">create</property>
        <property name="show_sql">true</property>  
  <property name="format_sql">true</property>  
     
        <mapping class="com.tutorialsdesk.inheritance.Employee"/>
        <mapping class="com.tutorialsdesk.inheritance.Contract_Employee"/>
       <mapping class="com.tutorialsdesk.inheritance.Regular_Employee"/>
    </session-factory>
</hibernate-configuration>



Create the class that stores the persistent object

In this class, we are simply storing the employee objects in the database.
File: StoreData.java
package com.tutorialsdesk.inheritance;

import org.hibernate.*;
import org.hibernate.cfg.*;

public class StoreData {
public static void main(String[] args) {
 AnnotationConfiguration cfg=new AnnotationConfiguration();
 Session session=cfg.configure("/conf/hibernate.cfg.xml").buildSessionFactory().openSession();
 
 Transaction t=session.beginTransaction();
 
 Employee e1=new Employee();
 e1.setName("sonoo");
 
 Regular_Employee e2=new Regular_Employee();
 e2.setName("Vivek Kumar");
 e2.setSalary(50000);
 e2.setBonus(5);
 
 Contract_Employee e3=new Contract_Employee();
 e3.setName("Arjun Kumar");
 e3.setPay_per_hour(1000);
 e3.setContract_duration("15 hours");
 
 session.persist(e1);
 session.persist(e2);
 session.persist(e3);
 
 t.commit();
 session.close();
 System.out.println("success");
}
}
Hibernate Table per concrete class hierarchy using annotations Tutorial with examples

Hibernate Table Per Subclass using Annotation Tutorial with examples

As we have specified earlier, in case of table per subclass strategy, tables are created as per persistent classes but they are reated using primary and foreign key. So there will not be duplicate columns in the relation.

We need to specify @Inheritance(strategy=InheritanceType.JOINED) in the parent class and @PrimaryKeyJoinColumn annotation in the subclasses.

Let's see the hierarchy of classes that we are going to map.

The table structure for each table will be as follows:
CREATE TABLE EMPLOYEE (
ID int IDENTITY,
NAME VARCHAR(50)

)


CREATE TABLE REGULAR_EMPLOYEE (
ID int ,
SALARY decimal(10,2),
BONUS decimal(10,2)
)

CREATE TABLE CONTRACT_EMPLOYEE (
ID int ,
PAY_PER_HOUR decimal(10,2),
CONTRACT_DURATION VARCHAR(50)
)

Example of Table per subclass class using Annotation

In this example we are creating the three classes and provide mapping of these classes in the hibernate.cfg.xml file.

Create the Persistent classes

You need to create the persistent classes representing the inheritance. Let's create the three classes for the above hierarchy:
File: Employee.java
package com.tutorialsdesk.inheritance;

import javax.persistence.*;

@Entity
@Table(name="EMPLOYEE")
@Inheritance(strategy = InheritanceType.JOINED) 

public class Employee{
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
    
@Column(name = "id")
private int id;

@Column(name = "name")
private String name;

public Employee() {
 
}

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


}
File: Regular_Employee.java
package com.tutorialsdesk.inheritance;

import javax.persistence.*;

@Entity  
@Table(name="REGULAR_EMPLOYEE")   
@PrimaryKeyJoinColumn(name="ID")  
public class Regular_Employee extends Employee{
 
@Column(name="salary") 
private float salary;

@Column(name="bonus") 
private int bonus;

public float getSalary() {
 return salary;
}

public void setSalary(float salary) {
 this.salary = salary;
}

public int getBonus() {
 return bonus;
}

public void setBonus(int bonus) {
 this.bonus = bonus;
}


}

File: Contract_Employee.java
package com.tutorialsdesk.inheritance;

import javax.persistence.AttributeOverrides;
import javax.persistence.AttributeOverride;
import javax.persistence.Column;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.Table;

@Entity  
@Table(name="CONTRACT_EMPLOYEE")   
@PrimaryKeyJoinColumn(name="ID")   
public class Contract_Employee extends Employee{
 
 @Column(name="pay_per_hour")
 private float pay_per_hour;
 
 @Column(name="contract_duration")
 private String contract_duration;

 public float getPay_per_hour() {
  return pay_per_hour;
 }

 public void setPay_per_hour(float pay_per_hour) {
  this.pay_per_hour = pay_per_hour;
 }

 public String getContract_duration() {
  return contract_duration;
 }

 public void setContract_duration(String contract_duration) {
  this.contract_duration = contract_duration;
 }


}

create configuration file

Open the hibernate.cgf.xml file, and add an entry of mapping resource like this:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
  "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
  "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">net.sourceforge.jtds.jdbc.Driver</property>
        <property name="hibernate.connection.password">PASSWORD</property>
        <property name="hibernate.connection.url">jdbc:jtds:sqlserver://localhost:1433/DBNAME</property>
        <property name="hibernate.connection.username">USERNAME</property>
        <property name="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</property>
     <property name="connection.pool_size">1</property>
        <property name="hbm2ddl.auto">create</property>
        <property name="show_sql">true</property>  
  <property name="format_sql">true</property>  
     
        <mapping class="com.tutorialsdesk.inheritance.Employee"/>
        <mapping class="com.tutorialsdesk.inheritance.Contract_Employee"/>
       <mapping class="com.tutorialsdesk.inheritance.Regular_Employee"/>
    </session-factory>
</hibernate-configuration>



Create the class that stores the persistent object

In this class, we are simply storing the employee objects in the database.
File: StoreData.java
package com.tutorialsdesk.inheritance;

import org.hibernate.*;
import org.hibernate.cfg.*;

public class StoreData {
public static void main(String[] args) {
 AnnotationConfiguration cfg=new AnnotationConfiguration();
 Session session=cfg.configure("/conf/hibernate.cfg.xml").buildSessionFactory().openSession();
 
 Transaction t=session.beginTransaction();
 
 Employee e1=new Employee();
 e1.setName("sonoo");
 
 Regular_Employee e2=new Regular_Employee();
 e2.setName("Vivek Kumar");
 e2.setSalary(50000);
 e2.setBonus(5);
 
 Contract_Employee e3=new Contract_Employee();
 e3.setName("Arjun Kumar");
 e3.setPay_per_hour(1000);
 e3.setContract_duration("15 hours");
 
 session.persist(e1);
 session.persist(e2);
 session.persist(e3);
 
 t.commit();
 session.close();
 System.out.println("success");
}
}


Hibernate Table Per Subclass using Annotation Tutorial with examples

Hibernate Table Per Hierarchy using Annotation Tutorial with examples

By this inheritance strategy, we can map the whole hierarchy by single table only. Here, an extra column (also known as discriminator column) is created in the table to identify the class.

Let's understand the problem first. I want to map the whole hierarchy given below into one table of the database.

You need to use @Inheritance(strategy=InheritanceType.SINGLE_TABLE), @DiscriminatorColumn and @DiscriminatorValue annotations for mapping table per hierarchy strategy.

In case of table per hierarchy, only one table is required to map the inheritance hierarchy. Here, an extra column (also known as discriminator column) is created in the table to identify the class.

Let's see the inheritance hierarchy:

The table structure for this hierarchy is as shown below:
CREATE TABLE EMPLOYEE (
ID int IDENTITY,
TYPE VARCHAR(50),
NAME VARCHAR(50),
SALARY decimal(10,2),
BONUS decimal(10,2),
PAY_PER_HOUR decimal(10,2),
CONTRACT_DURATION VARCHAR(50)
)

Example of Hibernate Table Per Hierarchy using Annotation

You need to follow following steps to create simple example:

  • Create the persistent classes
  • Create the configuration file
  • Create the class to store the fetch the data

Create the Persistent classes

You need to create the persistent classes representing the inheritance. Let's create the three classes for the above hierarchy:

File: Employee.java
package com.tutorialsdesk.inheritance;

import javax.persistence.*;

@Entity
@Table(name="EMPLOYEE")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="type",discriminatorType=DiscriminatorType.STRING)
@DiscriminatorValue(value="employee")

public class Employee{
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
    
@Column(name = "id")
private int id;

@Column(name = "name")
private String name;

public Employee() {
 
}

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


}

File: Regular_Employee.java
package com.tutorialsdesk.inheritance;

import javax.persistence.*;

@Entity
@DiscriminatorValue("regularemployee")
public class Regular_Employee extends Employee{
 
@Column(name="salary") 
private float salary;

@Column(name="bonus") 
private int bonus;

public float getSalary() {
 return salary;
}

public void setSalary(float salary) {
 this.salary = salary;
}

public int getBonus() {
 return bonus;
}

public void setBonus(int bonus) {
 this.bonus = bonus;
}


}

File: Contract_Employee.java
package com.tutorialsdesk.inheritance;

import javax.persistence.Column;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;

@Entity
@DiscriminatorValue("contractemployee")
public class Contract_Employee extends Employee{
 
 @Column(name="pay_per_hour")
 private float pay_per_hour;
 
 @Column(name="contract_duration")
 private String contract_duration;

 public float getPay_per_hour() {
  return pay_per_hour;
 }

 public void setPay_per_hour(float pay_per_hour) {
  this.pay_per_hour = pay_per_hour;
 }

 public String getContract_duration() {
  return contract_duration;
 }

 public void setContract_duration(String contract_duration) {
  this.contract_duration = contract_duration;
 }


}

Add the persistent classes in configuration file

Open the hibernate.cgf.xml file, and add entries of entity classes like this:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
  "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
  "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">net.sourceforge.jtds.jdbc.Driver</property>
        <property name="hibernate.connection.password">PASSWORD</property>
        <property name="hibernate.connection.url">jdbc:jtds:sqlserver://localhost:1433/DBNAME</property>
        <property name="hibernate.connection.username">USERNAME</property>
        <property name="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</property>
     <property name="connection.pool_size">1</property>
        <property name="hbm2ddl.auto">create</property>
        <property name="show_sql">true</property>  
  <property name="format_sql">true</property>  
     
        <mapping class="com.tutorialsdesk.inheritance.Employee"/>
        <mapping class="com.tutorialsdesk.inheritance.Contract_Employee"/>
       <mapping class="com.tutorialsdesk.inheritance.Regular_Employee"/>
    </session-factory>
</hibernate-configuration>



Create the class that stores the persistent object

In this class, we are simply storing the employee objects in the database.

File: StoreTest.java
package com.tutorialsdesk.inheritance;

import org.hibernate.*;
import org.hibernate.cfg.*;

public class StoreData {
public static void main(String[] args) {
 AnnotationConfiguration cfg=new AnnotationConfiguration();
 Session session=cfg.configure("/conf/hibernate.cfg.xml").buildSessionFactory().openSession();
 
 Transaction t=session.beginTransaction();
 
 Employee e1=new Employee();
 e1.setName("sonoo");
 
 Regular_Employee e2=new Regular_Employee();
 e2.setName("Vivek Kumar");
 e2.setSalary(50000);
 e2.setBonus(5);
 
 Contract_Employee e3=new Contract_Employee();
 e3.setName("Arjun Kumar");
 e3.setPay_per_hour(1000);
 e3.setContract_duration("15 hours");
 
 session.persist(e1);
 session.persist(e2);
 session.persist(e3);
 
 t.commit();
 session.close();
 System.out.println("success");
}
}

Hibernate Table Per Hierarchy using Annotation Tutorial with examples

Inheritance Mapping in Hibernate Tutorial with examples

Compared to JDBC we have one main advantage in hibernate, which is hibernate inheritance.

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.

Inheritance Mapping Strategies in Hibernate

Hibernate supports 3 types of Inheritance Mappings:
  1. Table per class hierarchy
  2. Table per sub-class hierarchy
  3. Table per concrete class hierarchy
Note: We can also called this Hibernate Inheritance Mapping as Hibernate Hierarchy

Table Per Hierarchy

In table per hierarchy mapping, single table is required to map the whole hierarchy, an extra column (known as discriminator column) is added to identify the class. But nullable values are stored in the table .

Table Per Concrete class

In case of table per concrete class, tables are created as per class. But duplicate column is added in subclass tables.

Table Per Subclass

In this strategy, tables are created as per class but related by foreign key. So there are no duplicate columns.
Inheritance Mapping in Hibernate Tutorial with examples