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;
}

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.

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.