In this approach every class of Inheritance hierarchy contains Its own database table. But the tables of Sub classs will maintain one-to-one relationship with table of Super class.
To configure Super class we can use <class> tag & and to configure Sub class we can use <joined- subclass> tags in Hibernate mapping file.
The <joined-subclass> tag is used to map the Sub class with Super class Using the primary key and foreign key relation
Note that a foreign key relationship exists between the subclass tables and super
class table. Thus the common data is stored in Person_Details table and subclass specific fields are stored in Employee_Details and Customer_Details tables.
SQL Scipt :
Create Database Tables
SQL> CREATE TABLE person_details ( personid Number NOT NULL , firstname VARCHAR(20) NOT NULL , lastname VARCHAR(15) NOT NULL , PRIMARY KEY (personid)
);
SQL>CREATE TABLE employee_details( empNo Number NOT NULL,
joiningDate DATE NULL , deptName VARCHAR(20) , deptNo Number NOT NULL, salary Number NOT NULL, PRIMARY KEY (empNo),
CONSTRAINT FK_PERSON1 FOREIGN KEY (empNo) REFERENCES person_details (personid) );
SQL>CREATE TABLE customer_details( customerId Number NOT NULL, orderdate DATE NULL ,
orderName VARCHAR(20) , PRIMARY KEY (customerId),
CONSTRAINT FK_PERSON2 FOREIGN KEY (customerId) REFERENCES person_details (personid) )
Example :
Person.java
package com.nareshit.pojo; public class Person {
private int personId;
private String firstName,lastName; public int getPersonId() {
return personId;
}
public void setPersonId(int personId) { this.personId = personId;
}
public String getFirstName() { return firstName;
}
public void setFirstName(String firstName) { this.firstName = firstName;
}
public String getLastName() { return lastName;
}
public void setLastName(String lastName) { this.lastName = lastName;
} }
Employee.java
package com.nareshit.pojo; import java.util.Date;
public class Employee extends Person{ private int deptNo;
private double salary; private String deptName; private Date joiningDate; public int getDeptNo() {
return deptNo;
}
public void setDeptNo(int deptNo) { this.deptNo = deptNo;
}
public double getSalary() { return salary;
}
public void setSalary(double salary) { this.salary = salary;
}
public String getDeptName() { return deptName;
}
public void setDeptName(String deptName) { this.deptName = deptName;
}
public Date getJoiningDate() { return joiningDate;
}
public void setJoiningDate(Date joiningDate) { this.joiningDate = joiningDate; } } Customer.java package com.nareshit.pojo; import java.util.Date;
public class Customer extends Person{ private String orderName;
private Date orderDate;
return orderName;
}
public void setOrderName(String orderName) { this.orderName = orderName;
}
public Date getOrderDate() { return orderDate;
}
public void setOrderDate(Date orderDate) { this.orderDate = orderDate;
} }
PersonDetails.hbm.xml
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.nareshit.pojo">
<class name="Person" table="Person_Details"> <id name="personId">
<generator class="increment"/> </id>
<property name="firstName" length="15"/> <property name="lastName" length="15"/> <joined-subclass name="Employee"
table="Employee_Details"> <key column="empNo"/>
<property name="deptNo" length="10"/> <property name="deptName" length="15"/> <property name="salary" length="15"/> <property name="joiningDate" /> </joined-subclass>
<joined-subclass name="Customer" table="Customer_Details">
<key column="customerId" />
<property name="orderName" length="15"/> <property name="orderDate" length="15"/> </joined-subclass>
</class>
</hibernate-mapping>
The joined-subclass subelement of class, specifies the subclass. The key subelement of joined- subclass is used to generate the foreign key in the subclass mapped table. This foreign key will be associated with the primary key of parent class mapped table.
hibernate.cfg.xml
<!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="connection.driver_class"> oracle.jdbc.driver.OracleDriver</property> <property name="connection.url"> jdbc:oracle:thin:@localhost:1521:XE</property> <property name="connection.username">system</property> <property name="connection.password">manager</property> <property name="dialect">org.hibernate.dialect.Oracle9Dialect</property> <property name="show_sql">true</property> <property name="hbm2ddl.auto">update</property> <mapping resource="com/nareshit/mapping/PersonDetails.hbm.xml"/> </session-factory> </hibernate-configuration> Test.java package com.nareshit.client; import java.util.Date; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import com.nareshit.pojo.Customer; import com.nareshit.pojo.Employee; public class Test {
public static void main(String[] args) { Test test=new Test();
Configuration cfg=new Configuration();
cfg.configure("/com/nareshit/config/hibernate.cfg.xml"); SessionFactory factory=cfg.buildSessionFactory();
Session session=factory.openSession(); System.out.println("Testing of Create Employee "); test.createEmployee(session);
System.out.println("Testing of Create Customer "); test.createCustomer(session);
System.out.println("Testing of Display Customer "); test.displayCustomer(session);
System.out.println("Testing of Display Employee "); test.displayEmployee(session);
}
public void displayEmployee(Session session){
Employee emp=(Employee)session.get(Employee.class,new Integer(1)); System.out.println(emp.getFirstName());
System.out.println(emp.getDeptName()); System.out.println(emp.getSalary()); }
public void displayCustomer(Session session) {
Customer c=(Customer)session.get(Customer.class,new Integer(2)); System.out.println(c.getFirstName());
System.out.println(c.getOrderDate()); }
public void createEmployee(Session session){ Employee emp=new Employee(); emp.setFirstName("Ramu"); emp.setLastName("A"); emp.setDeptNo(12); emp.setDeptName("sales"); emp.setSalary(12000); emp.setJoiningDate(new Date("12/12/2012")); session.save(emp); session.beginTransaction().commit(); }
public void createCustomer(Session session){ Transaction tx=session.beginTransaction(); Customer c=new Customer();
c.setFirstName("B"); c.setLastName("Sathish"); c.setOrderName("Keyboard"); c.setOrderDate(new Date("11/12/2012")); session.save(c); tx.commit(); } }
Example 2: With Annotation mapping
Person.java package com.nareshit.pojo; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Inheritance; import javax.persistence.InheritanceType; import javax.persistence.Table; import org.hibernate.annotations.GenericGenerator; @Entity @Table(name="person_details") @Inheritance(strategy=InheritanceType.JOINED)
public class Person { @Id
@GenericGenerator(name="myGenerator",strategy="increment") @GeneratedValue(generator="myGenerator")
private Integer personId;
private String firstName,lastName; public Integer getPersonId() {
return personId; }
public void setPersonId(Integer personId) { this.personId = personId;
}
public String getFirstName() { return firstName; }
public void setFirstName(String firstName) { this.firstName = firstName;
}
public String getLastName() { return lastName; }
public void setLastName(String lastName) { this.lastName = lastName; } } Employee.java package com.nareshit.pojo; import java.util.Date; import javax.persistence.Entity; import javax.persistence.PrimaryKeyJoinColumn; import javax.persistence.Table; @Entity @Table(name="employee_details") @PrimaryKeyJoinColumn(name="empNo") public class Employee extends Person {
private Integer deptNo; private String deptName; private Double salary; private Date joiningDate; public Integer getDeptNo() {
return deptNo; }
public void setDeptNo(Integer deptNo) { this.deptNo = deptNo;
}
public String getDeptName() { return deptName; }
public void setDeptName(String deptName) { this.deptName = deptName;
}
public Double getSalary() { return salary; }
public void setSalary(Double salary) { this.salary = salary;
}
public Date getJoiningDate() { return joiningDate; }
public void setJoiningDate(Date joiningDate) { this.joiningDate = joiningDate; } } Customer.java package com.nareshit.pojo; import java.util.Date; import javax.persistence.Entity; import javax.persistence.PrimaryKeyJoinColumn; import javax.persistence.Table; @Entity @Table(name="customer_details") @PrimaryKeyJoinColumn(name="customerId") public class Customer extends Person {
private String orderName; private Date orderDate;
public String getOrderName() { return orderName; }
public void setOrderName(String orderName) { this.orderName = orderName;
}
public Date getOrderDate() { return orderDate; }
public void setOrderDate(Date orderDate) { this.orderDate = orderDate;
} }
Both Employee and Customer classes are child of Person class. Thus while specifying the mappings, we used @PrimaryKeyJoinColumn to map it to parent table.
@PrimaryKeyJoinColumn – This annotation specifies a primary key column that is used as a foreign
It is used to join the primary table of an entity subclass in the JOINED mapping strategy to the primary table of its superclass; it is used within a SecondaryTable annotation to join a secondary table to a primary table; and it may be used in a OneToOne mapping in which the primary key of the referencing entity is used as a foreign key to the referenced entity.
If no PrimaryKeyJoinColumn annotation is specified for a subclass in the JOINED mapping strategy, the foreign key columns are assumed to have the same names as the primary key columns of the primary table of the superclass
Test.java package com.nareshit.client; import java.util.Date; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import com.nareshit.pojo.Customer; import com.nareshit.pojo.Employee; public class Test {
public static void main(String[] args) { Test test=new Test();
Configuration cfg=new Configuration();
cfg.configure("/com/nareshit/config/hibernate.cfg.xml"); SessionFactory factory=cfg.buildSessionFactory();
Session session=factory.openSession(); System.out.println("Testing of Create Employee "); test.createEmployee(session);
System.out.println("Testing of Create Customer "); test.createCustomer(session);
System.out.println("Testing of Display Customer "); test.displayCustomer(session);
System.out.println("Testing of Display Employee "); test.displayEmployee(session);
}
public void displayEmployee(Session session){
Employee emp=(Employee)session.get(Employee.class,new Integer(1)); System.out.println(emp.getFirstName());
System.out.println(emp.getDeptName()); System.out.println(emp.getSalary()); }
public void displayCustomer(Session session) {
Customer c=(Customer)session.get(Customer.class,new Integer(2)); System.out.println(c.getFirstName());
System.out.println(c.getOrderName()); System.out.println(c.getOrderDate()); }
public void createEmployee(Session session){ Employee emp=new Employee();
emp.setFirstName("Ramu"); emp.setLastName("A"); emp.setDeptNo(12); emp.setDeptName("sales"); emp.setSalary(12000); emp.setJoiningDate(new Date("12/12/2012")); session.save(emp); session.beginTransaction().commit(); }
public void createCustomer(Session session){ Transaction tx=session.beginTransaction(); Customer c=new Customer();
c.setFirstName("B"); c.setLastName("Sathish"); c.setOrderName("Keyboard"); c.setOrderDate(new Date("11/12/2012")); session.save(c); tx.commit(); } }
In Table per class hierarchy we design table with huge no.of columns. This is against of database designing. But In Table Per sub class approach
Multiple table will be there in shorter form & having the relationship along them .
so this is good database designing. In Real world the Regularly used Inheritance mapping approach is Table-per sub class.
In Table per sub class of Inheritance mapping each record of Sub tables maintains One to one relationship with Super table.