Hibernate - Table Per Hierarchy using Annotation

Hibernate - Table Per Hierarchy using Annotation

The "Table Per Hierarchy" strategy is a Hibernate inheritance mapping technique where entities of different types (subclasses) are stored in a single table. A discriminator column is used to differentiate between the types.

In this tutorial, we'll explore the "Table Per Hierarchy" inheritance strategy using annotations.

1. Setting up:

Make sure you've set up a Hibernate project with the necessary configurations and dependencies.

2. Define the Entity Classes:

Base Class (Vehicle):

This class will have a discriminator column to identify the type of vehicle - either Car or Bike.

@Entity @Table(name = "VEHICLE") @Inheritance(strategy = InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name = "VEHICLE_TYPE", discriminatorType = DiscriminatorType.STRING) public abstract class Vehicle { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String manufacturer; // Getters, setters, constructors... } 

Here, @Inheritance is set to InheritanceType.SINGLE_TABLE, and @DiscriminatorColumn is used to specify the name and type of the discriminator column.

Concrete Subclasses (Car and Bike):

@Entity @DiscriminatorValue("Car") public class Car extends Vehicle { private int numberOfSeats; // Getters, setters, constructors... } @Entity @DiscriminatorValue("Bike") public class Bike extends Vehicle { private int saddleHeight; // Getters, setters, constructors... } 

Notice the @DiscriminatorValue annotation that indicates the value of the discriminator column for each entity type.

3. Persistence:

When you persist an instance of Car:

Car car = new Car(); car.setManufacturer("Toyota"); car.setNumberOfSeats(4); session.save(car); 

Hibernate will insert a new row in the VEHICLE table with a VEHICLE_TYPE of "Car".

4. Fetching:

Fetching is like usual. When you fetch a Car entity, Hibernate will get it from the VEHICLE table using the discriminator column.

Car retrievedCar = session.get(Car.class, carId); 

5. Benefits & Drawbacks:

Benefits:

  • Simplified schema with a single table for all entities in the hierarchy.
  • Fetching entities is straightforward as there's only one table to query.

Drawbacks:

  • Columns specific to subclasses will be nullable in the table, which may lead to inefficient data storage.
  • If subclasses have many unique columns, the table can become wide with many nullable columns, which is not optimal.
  • Updating the inheritance hierarchy (adding/removing subclasses or changing properties) may require schema changes.

Conclusion:

The "Table Per Hierarchy" strategy is a concise and efficient way of storing entities of an inheritance hierarchy in a single table using a discriminator column. While it's a common and popular approach, always consider your application's needs and potential future changes when deciding on an inheritance mapping strategy.

Examples

  1. Hibernate table per hierarchy mapping example:

    • Table per hierarchy inheritance strategy in Hibernate allows mapping an entire hierarchy of classes to a single table.
    • Use @Entity and @Inheritance(strategy = InheritanceType.SINGLE_TABLE) annotations.
    // Parent class @Entity @Inheritance(strategy = InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name = "animal_type", discriminatorType = DiscriminatorType.STRING) public abstract class Animal { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; // Common fields and methods } // Subclass @Entity @DiscriminatorValue("CAT") public class Cat extends Animal { private String color; // Cat-specific fields and methods } // Subclass @Entity @DiscriminatorValue("DOG") public class Dog extends Animal { private String breed; // Dog-specific fields and methods } 
  2. Configuring table per hierarchy inheritance in Hibernate:

    • Configure table per hierarchy inheritance in Hibernate using the @Inheritance annotation with strategy = InheritanceType.SINGLE_TABLE.
    @Entity @Inheritance(strategy = InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name = "animal_type", discriminatorType = DiscriminatorType.STRING) public abstract class Animal { // Common fields and methods } 
  3. Mapping hierarchical classes with Hibernate annotations:

    • Map hierarchical classes using @Entity annotations for each class, @Inheritance(strategy = InheritanceType.SINGLE_TABLE), and @DiscriminatorColumn.
    @Entity @Inheritance(strategy = InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name = "animal_type", discriminatorType = DiscriminatorType.STRING) public abstract class Animal { // Common fields and methods } @Entity @DiscriminatorValue("CAT") public class Cat extends Animal { // Cat-specific fields and methods } @Entity @DiscriminatorValue("DOG") public class Dog extends Animal { // Dog-specific fields and methods } 
  4. Hibernate @Inheritance annotation for table per hierarchy:

    • Use @Inheritance(strategy = InheritanceType.SINGLE_TABLE) to specify the table per hierarchy inheritance strategy in Hibernate.
    @Entity @Inheritance(strategy = InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name = "animal_type", discriminatorType = DiscriminatorType.STRING) public abstract class Animal { // Common fields and methods } 
  5. Handling associations in table per hierarchy mapping:

    • Handle associations in table per hierarchy mapping by defining relationships in the annotated classes.
    @Entity @Inheritance(strategy = InheritanceType.SINGLE_TABLE) @DiscriminatorColumn(name = "animal_type", discriminatorType = DiscriminatorType.STRING) public abstract class Animal { // Common fields and methods } @Entity @DiscriminatorValue("CAT") public class Cat extends Animal { // Cat-specific fields and methods @ManyToOne @JoinColumn(name = "owner_id") private Person owner; } 
  6. HQL queries for table per hierarchy inheritance in Hibernate:

    • Use HQL (Hibernate Query Language) for queries specific to the table per hierarchy strategy.
    String hql = "FROM Animal WHERE color = :color"; Query query = session.createQuery(hql); query.setParameter("color", "black"); List<Animal> blackAnimals = query.list(); 

More Tags

responsive fullcalendar-4 react-native-image-picker c#-ziparchive hierarchical-data core-data new-operator entity-framework-migrations state tslint

More Programming Guides

Other Guides

More Programming Examples