Using Table per subclass strategy

Hibernate Table per subclass strategy

When using this strategy, the superclass has a table and each subclass has a table that contains only un-inherited properties: the subclass tables have a primary key that is a foreign key of the superclass.
Example:

package com.sample
public class Vehicle {
    // Constructors and Getter/Setter methods,
    long id;
    int noOfTyres;
    private String colour;

}
package com.sample
public class Car extends Vehicle {
    // Constructors and Getter/Setter methods,
    private String licensePlate;
    long price;
    int speed;

}

Table per subclass hierarchy
To use the table per class hierarchy strategy, you need to represent this structure in database, using two tables, referenced by a foreign key of the superclass.

Table per subclass strategy
Here’s the hibernate configuration:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 
<hibernate-mapping package="com.sample">
 
    <class name="Vehicle" table="VEHICLE"  >
        <id name="id" column="VEHICLE_ID">
            <generator class="native" />
        </id>


        <property name="noOfTyres" type="integer" column="NO_OF_TYRES" />
        <property name="colour" type="string"  />
 
        <joined-subclass name="Car" extends="Vehicle" table="CAR" >
                <key column="vehicle_id" />
                <property name="licensePlate" column="LICENSE_PLATE" />
                <property name="price" type="long"   />
                <property name="speed" type="integer"   />
        </joined-subclass>
    </class>
</hibernate-mapping>

Here the subclass is mapped using the joined-subclass element ( the subclass table is mapped with the optional attribute table).
This is the same, using JPA Annotations:

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;
 
@Entity
@Table(name = "VEHICLE")
@Inheritance(strategy=InheritanceType.JOINED)

public class Vehicle {
 
    @Id
    @GeneratedValue
    @Column(name = "VEHICLE_ID")
    private Long id;
     
    @Column(name="NO_OF_TYRES")
    int noOfTyres;
     
    @Column
    private String colour;
     
    // Constructors and Getter/Setter methods,
}
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
 
@Entity
@Table(name="CAR")
@PrimaryKeyJoinColumn(name="VEHICLE_ID")
public class Car extends Vehicle {

    @Column(name="license_plate")
    private String licensePlate;

    @Column
    long price;

    @Column
    int speed;


    // Constructors and Getter/Setter methods,
}

Notice the @PrimaryKeyJoinColumn annotation which specifies a primary key column that is used as a foreign key to join to another table.

 
        SessionFactory sf = HibernateUtil.getSessionFactory();
        Session session = sf.openSession();
        session.beginTransaction();
 
        // This will insert data in the VEHICLE table 
        Vehicle v = new Vehicle(1, 4, "red");
        session.save(v);
       // This will insert data in the VEHICLE table and in the CAR table
        Car car = new Car(1, 4, "red","AB123456", 15000l, 200);
        session.save(c);
         
        session.getTransaction().commit();
        session.close();

Advantage

Does not require complex changes to the database schema when a single parent class is modified. You should use this strategy when there is a requirement to use polymorphic associations and polymorphic queries.
Disadvantage

When the class hierarchy is spread across many classes (depth of inheritance), this strategy can have an impact on performance.