Hibernate Mapping Strategy :Table per subclass
As the name suggest, we have table define for each class(abstract, interface or concrete).
Example :
As in this Example, we have one superclass Employee and 2 subclass PermanentEmployee and ContractEmployee. At the database level, we have 3 tables Employee, PermanentEmployee and ContractEmployee. Here Primary key of Employee table acts as both primary key and foreign key for PermanentEmployee and ContractEmployee tables.
Java Class :
Employee.java
package com.demo.example1.pojo;
public class Employee {
private String name;
private String email;
private Long empId;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Long getEmpId() {
return empId;
}
public void setEmpId(Long empId) {
this.empId = empId;
}
}
As the name suggest, we have table define for each class(abstract, interface or concrete).
Example :
As in this Example, we have one superclass Employee and 2 subclass PermanentEmployee and ContractEmployee. At the database level, we have 3 tables Employee, PermanentEmployee and ContractEmployee. Here Primary key of Employee table acts as both primary key and foreign key for PermanentEmployee and ContractEmployee tables.
Java Class :
Employee.java
package com.demo.example1.pojo;
public class Employee {
private String name;
private String email;
private Long empId;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Long getEmpId() {
return empId;
}
public void setEmpId(Long empId) {
this.empId = empId;
}
}
PermanentEmployee.java
package com.demo.example1.pojo;
import java.util.Date;
public class PermanentEmployee extends Employee {
private String designation;
private Date joiningDate;
public String getDesignation() {
return designation;
}
public void setDesignation(String designation) {
this.designation = designation;
}
public Date getJoiningDate() {
return joiningDate;
}
public void setJoiningDate(Date joiningDate) {
this.joiningDate = joiningDate;
}
}
ContractEmployee.java
package com.demo.example1.pojo;
import java.util.Date;
public class ContractEmployee extends Employee {
private Date contractDate;
public Date getContractDate() {
return contractDate;
}
public void setContractDate(Date contractDate) {
this.contractDate = contractDate;
}
}
hbm file :
<hibernate-mapping package="com.demo.example1.pojo">
<class name="Employee" table="employee">
<id name="empId" column="empId" type="long">
<generator class="identity"/>
</id>
<property name="name" column="name" type="string"></property>
<property name="email" column="email" type="string" ></property>
<joined-subclass name="PermanentEmployee" table="PermanentEmployee" >
<key column="perm_emp_id"/>
<property name="designation" column="designation" />
<property name="joiningDate" column="joiningDate" type="timestamp" />
</joined-subclass>
<joined-subclass name="ContractEmployee" table="ContractEmployee">
<key column="contract_emp_id"/>
<property name="contractDate" column="contractDate" type="timestamp" />
</joined-subclass>
</class>
</hibernate-mapping>
Main Class :
package com.demo.example1;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.demo.example1.pojo.ContractEmployee;
import com.demo.example1.pojo.Employee;
import com.demo.example1.pojo.PermanentEmployee;
public class Test {
public static void main(String[] args) {
// First unit of work
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction tx = session.beginTransaction();
PermanentEmployee pm = new PermanentEmployee();
pm.setDesignation("perm_desg") ;
pm.setEmail("simon@test.com");
pm.setName("Simon") ;
session.save(pm);
ContractEmployee cm = new ContractEmployee();
cm.setEmail("nathen@test.com");
cm.setName("Nathen") ;
session.save(cm) ;
List<Employee> em = session.createQuery("from Employee").list();
System.out.println(em.size());
tx.commit();
session.close();
HibernateUtil.shutdown();
}
}
Output :
Hibernate:
/* insert com.demo.example1.pojo.PermanentEmployee
*/ insert
into
employee
(name, email)
values
(?, ?)
Hibernate:
/* insert com.demo.example1.pojo.PermanentEmployee
*/ insert
into
PermanentEmployee
(designation, joiningDate, perm_emp_id)
values
(?, ?, ?)
Hibernate:
/* insert com.demo.example1.pojo.ContractEmployee
*/ insert
into
employee
(name, email)
values
(?, ?)
Hibernate:
/* insert com.demo.example1.pojo.ContractEmployee
*/ insert
into
ContractEmployee
(contractDate, contract_emp_id)
values
(?, ?)
Hibernate:
/*
from
Employee */ select
employee0_.empId as empId1_,
employee0_.name as name1_,
employee0_.email as email1_,
employee0_1_.designation as designat2_2_,
employee0_1_.joiningDate as joiningD3_2_,
employee0_2_.contractDate as contract2_3_,
case
when employee0_1_.perm_emp_id is not null then 1
when employee0_2_.contract_emp_id is not null then 2
when employee0_.empId is not null then 0
end as clazz_
from
employee employee0_
left outer join
PermanentEmployee employee0_1_
on employee0_.empId=employee0_1_.perm_emp_id
left outer join
ContractEmployee employee0_2_
on employee0_.empId=employee0_2_.contract_emp_id
2
Advantage :
- The SQL schema is Normalized.
- A polymorphic association to a particular subclass is represented as a foreign key referencing the table of that subclass
Disadvantage :
- Relies on outer join when querying for Employee class as shown in output .
No comments:
Post a Comment