Discriminator element creates a column with name "Type", value of which will indicate whether a particular record is Employee or Physician. There is also a special property "abstract" in class element which tells that object of person can't be created.
Hibernate mapping for Employee is shown below:
"subclass" element indicates that there is a class per hierarchy strategy of inheritance between Employee and Person. "extends" property of subclass element creates relationship of "Employee" with "Person". "discriminator-value" tells hibernate to use "Employee" in discriminator column to identify all employees.
Configuration for Physician is given below:
Now lets add two Persons: one is Employee and other is Physician as shown below:
Session session = HibernateUtil.getSessionFactory().openSession(); session.beginTransaction(); Emplo
yee emp = new Employee(); emp.setName("Amer Sohail"); emp.setPay(123f); session.save(emp); Physician phy = new Physician(); phy.setName("Dr. Amer Sohail"); phy.setPay(345f);
phy.setBillingAddress("Lahore");
phy.setSpeciality("Pediatrics"); session.save(phy); session.getTransaction().commit(); session.close();
a single table with name "person" will be created in the database with following two records:
Lets retrieve the all person from database and you will observe polymorphic feature of hibernate:
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
List emp = session.createQuery("from Person emp").list();
if (emp != null && emp.size() > 0)
{
for (int index = 0; index <>
{
System.out.println("Name of employee is " +((Employee)emp.get(index)).getName());
if (emp.get(index) instanceof Person)
System.out.println("This is person");
if (emp.get(index) instanceof Employee)
System.out.println("This is Employee");
if (emp.get(index) instanceof Physician)
System.out.println("This is Physician");
}
}
session.getTransaction().commit();
session.close();
output of the code will be following:
Name of employee is Amer Sohail
This is person
This is Employee
Name of employee is Dr. Amer Sohail
This is person
This is Employee
This is Physician
As shown in output, i just retrieved "persons" but it instantiated objects of type to which they belong e.g. Amer Sohail was just an employee not a physician so hibernate created it of "Employee" type. This is really a very powerful feature of hibernate.
Now if i want to retrieve only employee not physician, then i will write the following query:
List emp = session.createQuery("from Employee emp where type = Employee").list();
I explained the strategy "class-per-heirarchy" in this blog's post. This strategy has one major drawback which you should notice while viewing records in table. It contains "nulls" against those records which are not in employee like "speciality" and "billing_address". Since DBMS has to handle null fields with a special case and it creates an impact on performance so that is the major drawback of this strategy because it will create a lot of nulls in the table. but on the other handle, no join is needed so no join cost improves the performance. Now there is very interesting situation bcz pros of this blog says it increase the performance while cons says it decreases the performance so what is the net effect. you have to wait for it for later posts in which i will compare all the strategies.