Hibernate Inheritance
// 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.
page revision: 6, last edited: 06 Aug 2017 19:27