jobs4timesLogo jobs4timesLogo

Hibernate Inheritance

Agenda :
  1. Table per class
  2. Table per sub-class
  3. Table per concrete-class

Hibernate Inheritance :

Hibernate supports 3 types of Inheritance
  1. Table per class
  2. Table per sub-class
  3. Table per concrete-class
In hibernate inheritance hierarchy if we save derived class object then base class object also will be stored into the database automatically.
  • Consider 3 POJO classes, Employee class as a base class and SalEmployee, HourEmployee as derived classes.
  • For all POJO classes we have only one mapping XML file which is nothing but Base class mapping file.
  • Both derived classes data has to map in base class mapping file only.
Table per class :
  • In Table per class hierarchy, both base class and derived class data will be stored into a single table which is base class related table.
  • For all 3 POJO classes we have single mapping file which is for base (Employee) class.
  • To map derived classes details into base class mapping file , we need to use <subclass> tag.
  • Here if we save either HourEmployee or SalEmployee then automatically Employee object also will be stored into database. Both derived class object (HourEmployee/SalEmployee) and base class object(Employee) will be stored into Employee related table only.
  • In Table per class hiierarchy, we need to use one special column in the database table which is known as discriminator.
  • Discriminator column will help us to identify which derived class object is stored along with base class object.

Employee.java

package com.beans;

public class Employee {
private long employeeId;
private String employeeName;


public long getEmployeeId() {
	return employeeId;
}
public void setEmployeeId(long employeeId){
	this.employeeId = employeeId;
}
public String getEmployeeName(){
	return employeeName;
}
public void setEmployeeName(String employeeName){
	this.employeeName = employeeName;

}

}

SalEmployee.java

package com.beans;

public class SalEmployee extends Employee{
private double salary;

public double getSalary() {
	return salary;
}
public void setSalary(double salary) {
	this.salary = salary;
}

}

HoursEmployee.java

package com.beans;

public class HourEmployee extends Employee{

private int workHours;

public int getWorkHours() {
	return workHours;
}

public void setWorkHours(int workHours) {
	this.workHours = workHours;
}

}
Employee.hbm.xml
<hibernate-mapping>

<class name="com.beans.Employee" table="EMPLOYEEDB" >
  <id name="employeeId" column="EID"/>
  <discriminator column="discolumn" type="string" length="15"/>
  <property name="employeeName" column="ENAME" length="30"/>
  
  <subclass name="com.beans.SalEmployee" discriminator-value="se">
    <property name="salary" column="ESAL"/>
  </subclass>
  
  <subclass name="com.beans.HourEmployee" discriminator-value="he">
  <property name="workHours" column="hours"/>
  </subclass>
         
</class>

</hibernate-mapping>
hibernate.cfg.xml
<hibernate-configuration>

<session-factory>

<!-- Related to the connection properties -->

<property name="myeclipse.connection.profile">myJdbcDriver</property>
<property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>
<property name="connection.url">jdbc:oracle:thin:@localhost:1521:xe</property>
<property name="connection.username">lms</property>
<property name="connection.password">scott</property>


<!-- Related to the hibernate properties -->
<property name="dialect">org.hibernate.dialect.Oracle9Dialect</property>
<property name="show_sql">true</property>
<property name="hbm2ddl.auto">create</property>

<!-- Related to hibernate mapping -->
<mapping resource="com/hiber/Employee.hbm.xml" />

</session-factory>

</hibernate-configuration>
Client Application :
package com.client;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

import com.beans.HourEmployee;
import com.beans.SalEmployee;

public class ClientApp{

public static void main(String ar[]){

Configuration cfg=new Configuration();
cfg.configure();

SessionFactory sf=cfg.buildSessionFactory();
Session session=sf.openSession();
Transaction tx=session.beginTransaction();

SalEmployee sal=new SalEmployee();
sal.setEmployeeId(10L);
sal.setEmployeeName("charan");
sal.setSalary(5000);

HourEmployee hour=new HourEmployee();
hour.setEmployeeId(11L);
hour.setEmployeeName("Akshay");
hour.setWorkHours(6000);

session.save(sal);
session.save(hour);

tx.commit();

System.out.println("success");

}
}

Table per sub-class :
  • In Table per class, both derived class object and base class object are stored in base class related table only, which means for all POJO classes we have single table.
  • But in Table per sub-class, per each class we have a separate table(including subclass also).
    X number of classes = X number of tables .
  • In Table per sub-class also for all POJO classes we have one mapping file which is base classes mapping file. Derived class details we have to map in base class mapping file only.
  • To map derived class details inside base class mapping file, we use <joined-subclass> tag.
  • In Table per sub-class, discriminator column not required because each class data is stored in separate table. But we need to take one <key> tag, inside <joined-subclass> tag.

Note : POJO class, Mapping and Configuration files are same as above application.

Employee.hbm.xml
<hibernate-mapping>

<class name="com.beans.Employee" table="EMPLOYEEDB" >
  <id name="employeeId" column="EID"/>
  <property name="employeeName" column="ENAME" length="30"/>

  <joined-subclass name="com.beans.SalEmployee" table="SalEmployeeDB">
   <key column="refEID"/>
   <property name="salary" column="ESAL"/>
  </joined-subclass>  

  <joined-subclass name="com.beans.HourEmployee" table="HourEmployeeDB">
   <key column="refEID"/>
   <property name="workHours" column="HOURS"/>
  </joined-subclass>         
</class>

</hibernate-mapping>

Client Application :
package com.client;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

import com.beans.HourEmployee;
import com.beans.SalEmployee;

public class ClientApp {

public static void main(String ar[]){

Configuration cfg=new Configuration();
cfg.configure();

SessionFactory sf=cfg.buildSessionFactory();
Session session=sf.openSession();
Transaction tx=session.beginTransaction();

SalEmployee sal=new SalEmployee();
sal.setEmployeeId(10L);
sal.setEmployeeName("charan");
sal.setSalary(5000);

HourEmployee hour=new HourEmployee();
hour.setEmployeeId(11L);
hour.setEmployeeName("Akshay");
hour.setWorkHours(6000);

session.save(sal);
session.save(hour);

tx.commit();

System.out.println("success");

}
}
Table per concrete-class :
  • In Table per concrete class, we have tables only for derived classes.
    X number of derived classes = X number of tables
  • Here Base class data also will be saved into derived class related table.
  • One mapping file for all POJO classes. Here also we need to take mapping file only for base class.
  • To map derived class details we need to take <union-subclass> tag inside base class related mapping file.

Note : POJO class, Mapping and Configuration files are same as above application.

Employee.hbm.xml
<hibernate-mapping>

<class name="com.beans.Employee">
  <id name="employeeId" column="EID"/>
  <property name="employeeName" column="ENAME" length="30"/>
  
  <union-subclass name="com.beans.SalEmployee" table="SALEMPLOYEEDB">
   <property name="salary" column="ESAL"/>
  </union-subclass>
  
    <union-subclass name="com.beans.HourEmployee" table="HOUREMPLOYEEDB">
   <property name="workHours" column="HOURS"/>
  </union-subclass>         
</class>

</hibernate-mapping>
Client Application :
package com.client;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

import com.beans.HourEmployee;
import com.beans.SalEmployee;

public class ClientAppOne {

public static void main(String ar[]){

Configuration cfg=new Configuration();
cfg.configure();

SessionFactory sf=cfg.buildSessionFactory();
Session session=sf.openSession();
Transaction tx=session.beginTransaction();

SalEmployee sal=new SalEmployee();
sal.setEmployeeId(10L);
sal.setEmployeeName("charan");
sal.setSalary(5000);

HourEmployee hour=new HourEmployee();
hour.setEmployeeId(11L);
hour.setEmployeeName("Akshay");
hour.setWorkHours(6000);

session.save(sal);
session.save(hour);

tx.commit();

System.out.println("success");

}
}