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.
Found the article helpful? if so please follow us on Socials