Table Per Concrete Class with Unions
Consider this Example :
As in this Example, we have an abstract class Employee which is inherited by 2 concrete class PermanentEmployee and ContractEmployee. We have 2 tables PermanentEmployee and ContractEmployee to map this concrete class.
This mapping is very much similar to Table with Concrete class with implicit polymorphism hibernate mapping strategy except the fact that in this strategy the database identifier is defined in abstract class which is shared for by all concrete class in hierarchy. Example Employee class has primary key "empId" which is shared by PermanentEmployee and ContractEmployee class.
Java Class :
Employee Class :
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;
}
}
hbm files looks like :
<hibernate-mapping package="com.demo.example1.pojo">
<class name="Employee" abstract="true">
<id name="empId" column="empId" type="long">
<generator class="assigned"/>
</id>
<property name="name" column="name" access="field" />
<property name="email" column="email" access="field" />
<union-subclass table="permanentemployee" name="PermanentEmployee">
<property name="designation" column="designation" />
<property name="joiningDate" column="joiningDate" type="timestamp" />
</union-subclass>
<union-subclass table="contractemployee" name="ContractEmployee">
<property name="contractDate" column="contractDate" type="timestamp" />
</union-subclass>
</class>
</hibernate-mapping>
To Run :
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.Message;
import com.demo.example1.pojo.PermanentEmployee;
public class Test {
public static void main(String[] args) {
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction tx = session.beginTransaction();
PermanentEmployee pm = new PermanentEmployee();
pm.setDesignation("desg") ;
pm.setEmail("permEmployee@test.com");
pm.setName("Simon") ;
pm.setEmpId(1l);
session.save(pm);
ContractEmployee cm = new ContractEmployee();
cm.setEmail("contractEmployee@test.com");
cm.setName("Peter") ;
cm.setEmpId(2l);
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
permanentemployee
(name, email, designation, joiningDate, empId)
values
(?, ?, ?, ?, ?)
Hibernate:
/* insert com.demo.example1.pojo.ContractEmployee
*/ insert
into
contractemployee
(name, email, contractDate, empId)
values
(?, ?, ?, ?)
Hibernate:
/*
from
Employee */ select
employee0_.empId as empId1_,
employee0_.name as name1_,
employee0_.email as email1_,
employee0_.designation as designat1_2_,
employee0_.joiningDate as joiningD2_2_,
employee0_.contractDate as contract1_3_,
employee0_.clazz_ as clazz_
from
( select
null as contractDate,
joiningDate,
empId,
email,
name,
designation,
1 as clazz_
from
permanentemployee
union
select
contractDate,
null as joiningDate,
empId,
email,
name,
null as designation,
2 as clazz_
from
contractemployee
) employee0_
2
Consider this Example :
As in this Example, we have an abstract class Employee which is inherited by 2 concrete class PermanentEmployee and ContractEmployee. We have 2 tables PermanentEmployee and ContractEmployee to map this concrete class.
This mapping is very much similar to Table with Concrete class with implicit polymorphism hibernate mapping strategy except the fact that in this strategy the database identifier is defined in abstract class which is shared for by all concrete class in hierarchy. Example Employee class has primary key "empId" which is shared by PermanentEmployee and ContractEmployee class.
Java Class :
Employee Class :
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;
}
}
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;
}
}
<hibernate-mapping package="com.demo.example1.pojo">
<class name="Employee" abstract="true">
<id name="empId" column="empId" type="long">
<generator class="assigned"/>
</id>
<property name="name" column="name" access="field" />
<property name="email" column="email" access="field" />
<union-subclass table="permanentemployee" name="PermanentEmployee">
<property name="designation" column="designation" />
<property name="joiningDate" column="joiningDate" type="timestamp" />
</union-subclass>
<union-subclass table="contractemployee" name="ContractEmployee">
<property name="contractDate" column="contractDate" type="timestamp" />
</union-subclass>
</class>
</hibernate-mapping>
To Run :
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.Message;
import com.demo.example1.pojo.PermanentEmployee;
public class Test {
public static void main(String[] args) {
Session session = HibernateUtil.getSessionFactory().openSession();
Transaction tx = session.beginTransaction();
PermanentEmployee pm = new PermanentEmployee();
pm.setDesignation("desg") ;
pm.setEmail("permEmployee@test.com");
pm.setName("Simon") ;
pm.setEmpId(1l);
session.save(pm);
ContractEmployee cm = new ContractEmployee();
cm.setEmail("contractEmployee@test.com");
cm.setName("Peter") ;
cm.setEmpId(2l);
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
permanentemployee
(name, email, designation, joiningDate, empId)
values
(?, ?, ?, ?, ?)
Hibernate:
/* insert com.demo.example1.pojo.ContractEmployee
*/ insert
into
contractemployee
(name, email, contractDate, empId)
values
(?, ?, ?, ?)
Hibernate:
/*
from
Employee */ select
employee0_.empId as empId1_,
employee0_.name as name1_,
employee0_.email as email1_,
employee0_.designation as designat1_2_,
employee0_.joiningDate as joiningD2_2_,
employee0_.contractDate as contract1_3_,
employee0_.clazz_ as clazz_
from
( select
null as contractDate,
joiningDate,
empId,
email,
name,
designation,
1 as clazz_
from
permanentemployee
union
select
contractDate,
null as joiningDate,
empId,
email,
name,
null as designation,
2 as clazz_
from
contractemployee
) employee0_
2
Points To Note :
- Employee class has been declared as abstract in hbm file. Otherwise a separate table for instance of the superclass is needed. Here in this example, "assigned" id generation strategy is used which allows us to manually set the id of the instance.
- We cannot use Native or identity or such id generate strategy when using this Hibernate Mapping Strategy. Reason is primary key is to be shared across all union subclass of hierarchy.
No comments:
Post a Comment