Hibernate Inheritance

hibernate

// Specify strategy for dealing with inheritance.  This @Inheritance annotation is added to the base class.
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
@Inheritance(strategy=InheritanceType.JOINED)

// Not using multiple tables when dealing with inheritance:
We do not use multiple tables when dealing with inheritance because one table cannot 
have foreign key relationship with multiple tables.

Assume that we have a Vehicle class, and a TwoWheelVehicle class, and the 
TwoWheelVehicle class is a child class of the Vehicle class.
By default, Hibernate provides a "single table" inheritance strategy. 
Even though we marked the TwoWheelVehicle class with the @Entity annotation, 
Hibernate does not create a separate table for it. Instead, Hibernate use its 
"single table" inheritance strategy. It only creates the table for the base class. 
It adds a column named DTYPE to the Vehicle table, and fields from the child 
class to the parent table. The DTYPE column contains the name of the class.

// The discriminator column:
When Hibernate uses the "single table" inheritance strategy, it creates the column 
named DTYPE. This column stores the name of the class. This column is known as the 
discriminator. It is used to distinguish objects of different classes.

// Disadvantage with the "single-table" inheritance strategy:
This results in having a lot of columns that are null because of the fact that we
are storing objects of different classes in the same table.

// @Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
When this happens, Hibernate creates a table for each child class. It also add 
columns from the base class to the child class' table. This includes the primary 
key from the base class. This has certain advantages and disadvantages. 
The disadvantage is that the data for the base class is stored in both places, 
consuming more disk space, and the potential for data inconsistency if it is 
changed in one table and is not changed in all the tables by other process 
perhaps not using Hibernate, or we incorrectly use Hibernate. With Hibernate, 
if we need to have an object of the child class, we should go to the table of 
the child class, or use session.get with the child class. The advantage is that 
we avoid having to join the child table with the parent table.

// @Inheritance(strategy=InheritanceType.JOINED)
This is perhaps the best inheritance strategy. The is no "duplication of data", 
and there is no "null values everywhere". Hibernate creates one table for each 
class, and use the ID column from the base table as the foreign key in the 
child tables. Common information is stored in the base table. Information that 
is specific to the child class is stored in the child table.  However, the 
disadvantage of this strategy is that it use a join, so it does carry a 
performant penalty, perhaps not much, but it is there nonetheless.  We have to
benchmark, and balance the trade-off between performance and disk-space cost.

// Control the name of the discriminator column used in "single-table" inheritance strategy
// @DiscriminatorColumn is a field level annotation
@DiscriminatorColumn(
  name="VEHICLE_TYPE",
  discriminatorType=DiscriminatorType.STRING
)

// Control the values that is put into the discriminator column
// @DiscriminatorValue is a class-level annotation
@DiscriminatorValue("Bike")

@DiscriminatorColumn(   // Specify the name and type of the discriminator column
  name="VEHICLE_TYPE",  // This annotation is added to the base class.
  discriminatorType=DiscriminatorType.STRING
)

@DiscriminatorValue("Bike")     // Control the value that Hibernate puts into the  DTYPE
                                // (discriminator) column.  By default, Hibernate stores
                                // the name of the child class in the discriminator column.
Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License