As previously explained, the SINGLE_TABLE inheritance is the most efficient entity inheritance strategy.
However, for JPQL query such as this one:
List<Post> posts = entityManager .createQuery( "select p " + "from Post p " + "where p.board = :board", Post.class) .setParameter("board", board) .getResultList();
Hibernate generates a SQL query which filters by the associated discriminator column (e.g.
DTYPE by default):
SELECT t.id AS id2_1_, t.board_id AS board_id8_1_, t.createdOn AS createdO3_1_, t.owner AS owner4_1_, t.title AS title5_1_, t.content AS content6_1_ FROM topic t WHERE t.DTYPE = 'Post' AND t.board_id = 1
So, because we are filtering by the discriminator column, we might want to index it or include it to speed up queries.
However, the default
DiscriminatorType expects a
VARCHAR column that must hold the longest entity subclass name. For the
Announcement class, we need at least 12 bytes to store the entity class name while for the
Post entity, 4 bytes are required.
If the discriminator type column is indexed and we store 1 million
Announcement and 100 million
Post entities, the index will require 393 MB (12 + 400 million bytes). On the other hand, if the discriminator column is a
TINYINT (only 1 byte is needed to store a discriminator value), we need only 96 MB (1 + 100 million bytes).
In this article, I’m going to explain how you can get the most out of the
DiscriminatorType while still retaining the descriptiveness of the default