Single Table Inheritance

In our previous post we have seen that hibernate creates a single table even though there are different entities available. If we closely look at the output generated by hibernate for the Vehicle table, we can see an extra column "DTYPE" that it generates. DTYPE stands for discriminator type. This column is used to discriminate between the other two entities which are included in this table. They are TwoWheeler and FourWheeler.
Hibernate provides us with a @Inheritance annotation where we can specify the strategy that it has to use while creating the tables. By default the strategy is "SINGLE_TABLE". In this strategy hibernate creates a single table, like in our previous example and creates an extra column "DTYPE" to discriminate the other tables. There is an annotation using which we can customize the "DTYPE" name. It is using the annotation @DiscriminatorColumn. Using @DiscriminatorValue annotation we can customize the value in the "DTPE". The values in the DTYPE are nothing but the name of the other entities. Below example shows how to use these annotations.
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

    <session-factory>

        <!-- Database connection settings -->
        <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">hr</property>
        <property name="connection.password">hr</property>

        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">1</property>

        <!-- SQL dialect -->
        <property name="dialect">org.hibernate.dialect.OracleDialect</property>

        <!-- Disable the second-level cache  -->
        <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>

        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">true</property>

        <!-- Drop and re-create the database schema on startup -->
        <property name="hbm2ddl.auto">create</property>

        <!-- Names the annotated entity class -->
        <mapping class="com.ram.dao.Vehicle"/>
        <mapping class="com.ram.dao.TwoWheeler"/>
        <mapping class="com.ram.dao.FourWheeler"/>

    </session-factory>

</hibernate-configuration>
File: com.ram.dao.Vehicle.java
package com.ram.dao;

import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;

@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="Vehicle_Type", discriminatorType=DiscriminatorType.STRING)
public class Vehicle {
 @Id @GeneratedValue
 private int vehicleId;
 private String vehicleName;
 
 public int getVehicleId() {
  return vehicleId;
 }
 public void setVehicleId(int vehicleId) {
  this.vehicleId = vehicleId;
 }
 public String getVehicleName() {
  return vehicleName;
 }
 public void setVehicleName(String vehicleName) {
  this.vehicleName = vehicleName;
 }
}

File: com.ram.dao.TwoWheeler.java
package com.ram.dao;

import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;

@Entity
@DiscriminatorValue("Bike")
public class TwoWheeler extends Vehicle {
 private String steeringHandle;

 public String getSteeringHandle() {
  return steeringHandle;
 }

 public void setSteeringHandle(String steeringHandle) {
  this.steeringHandle = steeringHandle;
 }
}

File: com.ram.dao.FourWheeler.java
package com.ram.dao;

import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;

@Entity
@DiscriminatorValue("Car")
public class FourWheeler extends Vehicle {
 private String steeringWheel;

 public String getSteeringWheel() {
  return steeringWheel;
 }

 public void setSteeringWheel(String steeringWheel) {
  this.steeringWheel = steeringWheel;
 }
}

File: com.ram.hibernate.SingleTableInheritanceExample.java
package com.ram.hibernate;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

import com.ram.dao.FourWheeler;
import com.ram.dao.TwoWheeler;
import com.ram.dao.Vehicle;

public class SingleTableInheritanceExample {
 public static void main(String[] args) {

  Vehicle vehicle = new Vehicle();
  vehicle.setVehicleName("Car");
  
  TwoWheeler yamaha = new TwoWheeler();
  yamaha.setVehicleName("Yamaha");
  yamaha.setSteeringHandle("Yamaha steering handle");
  
  FourWheeler benz = new FourWheeler();
  benz.setVehicleName("Benz");
  benz.setSteeringWheel("Benz steering wheel");
  
  SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
  Session session = sessionFactory.openSession();
  
  session.beginTransaction();
  session.save(vehicle);
  session.save(yamaha);
  session.save(benz);
  
  session.getTransaction().commit();
  session.close();
 }
}

Execute the SingleTableInheritanceExample.java and you get the below output.

No comments:

Post a Comment