Hibernate Inheritance
Agenda :
- Table per class
- Table per sub-class
- Table per concrete-class
Hibernate Inheritance :
Hibernate supports 3 types of Inheritance
- Table per class
- Table per sub-class
- 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");
}
}
|