Home Table Per Hierarchy (Single Table Strategy)
Post
Cancel

Table Per Hierarchy (Single Table Strategy)

Table Per Hierarchy (Single Table Strategy):

Table per class hierarchy is a type of inheritance in which all of the fields from the superclass and the subclasses are stored in a single table, but the table includes a discriminator column that identifies the subclass to which each record belongs.

Example of Table Per Class Hierarchy Strategy

Let’s take the same last example, consider we have the following classes:

Vehicle (parent class) Car (subclass of Vehicle) Bike (subclass of Vehicle)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Vehicle {
    private Long id;
    private String make;
    private String model;
    // getters and setters
}

public class Car extends Vehicle {
    private Integer numOfDoors;
    // getters and setters
}

public class Bike extends Vehicle {
    private Boolean isElectric;
    // getters and setters
}

Database Table Structure for Table Per Class Hierarchy

Now, let’s take a look at the resulting database table that is generated by Hibernate:

1
2
3
4
5
6
7
8
9
10
11
CREATE TABLE vehicle (
    id bigint NOT NULL AUTO_INCREMENT,
    make varchar(255),
    model varchar(255),
    vehicle_type varchar(255),
    numOfDoors int,
    isElectric bit,
    PRIMARY KEY (id)
);

This table contains columns for all the attributes of all the classes in the hierarchy.

Entity Class Hierarchy

Here is what the Java class hierarchy might look like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Entity
@Table(name = "vehicle")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "vehicle_type", discriminatorType = DiscriminatorType.STRING)
public class Vehicle {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;

  private String make;
  private String model;

  // getters and setters
}

The @Inheritance annotation is used to specify the inheritance strategy, which in this case is InheritanceType.SINGLE_TABLE. The @DiscriminatorColumn annotation is used to specify the name of the discriminator column and the discriminator type, which in this case is DiscriminatorType.STRING.

Next, we need to specify the subclasses using the @DiscriminatorValue annotation. For example, in the Car class, we would add the following annotation:

1
2
3
4
5
6
7
@Entity
@DiscriminatorValue("Car")
public class Car extends Vehicle {
    private Integer numOfDoors;
    // getters and setters
}

In the Bike class, we would add the following annotation:

1
2
3
4
5
6
7
@Entity
@DiscriminatorValue("Bike")
public class Bike extends Vehicle {
    private Boolean isElectric;
    // getters and setters
}

Saving Entities

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();

Vehicle vehicle = new Vehicle();
vehicle.setMake("Toyota");
vehicle.setModel("Camry");

Car car = new Car();
car.setMake("Honda");
car.setModel("Civic");
car.setNumOfDoors(4);

Bike bike = new Bike();
bike.setMake("Yamaha");
bike.setModel("YZF-R6");
bike.setIsElectric(false);

session.save(vehicle);
session.save(car);
session.save(bike);

transaction.commit();
session.close();

Database Table Data View

idmakemodelnum_of_doorsis_electric
1ToyotaCamrynullnull
2HondaCivic4null
3YamahaYZF-R6nullfalse

Advantages:

  • It is simple and easy to understand, as all the classes in the hierarchy are mapped to a single database table.
  • It has good performance for read operations, as there is only one database table to read from.
  • It is useful when the inheritance hierarchy has many subclasses, as creating a separate table for each subclass can result in a large number of tables.

Disadvantages:

  • It can have poor performance for write operations, as there is only one table to write to, which can result in contention issues when multiple threads or processes try to write to the same table.
  • It can result in a table with many null values, as the table needs to contain columns for all the attributes of all the classes in the hierarchy, even if some of the attributes do not apply to some of the subclasses.
  • It can be difficult to query the table directly, as the discriminator column needs to be used to identify the type of object in each row.

Conclusion

The advantage of using table per class hierarchy is that it’s efficient in terms of database performance, since there is only one table to query. However, it can lead to a lot of null values in the table for fields that don’t apply to certain subclasses.

This post is licensed under CC BY 4.0 by the author.