✅ Short Answer
The TABLE_PER_CLASS strategy maps each concrete subclass in an inheritance hierarchy to its own separate table, each with all fields from the base class + subclass.
There’s no table for the abstract base class.
🔎 Detailed Explanation
🔹 In TABLE_PER_CLASS:
- Each concrete class (i.e., classes you can instantiate) has its own table.
- The table contains columns for all inherited fields from the base class + the subclass’s own fields.
- There is no common parent table — each subclass table is independent.
🔹 When you query the base type (polymorphic query), Hibernate performs a UNION of all subclass tables.
🧑💻 Example
Entities:
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public abstract class Animal {
@Id
private Long id;
private String name;
}
@Entity
public class Dog extends Animal {
private String breed;
}
@Entity
public class Cat extends Animal {
private boolean likesMilk;
}
Database tables created:
Table: dog
| id | name | breed |
Table: cat
| id | name | likes_milk |
⚠️ There is no animal table, only separate tables for concrete classes.
🔹 How Hibernate Queries with TABLE_PER_CLASS
- Polymorphic queries like:
SELECT a FROM Animal a
require Hibernate to issue a UNION query combining dog
and cat
tables, e.g.:
SELECT id, name, breed, NULL AS likes_milk FROM dog
UNION ALL
SELECT id, name, NULL AS breed, likes_milk FROM cat
📊 Advantages & Disadvantages
✅ Pros:
- Simple tables → each table only has relevant fields → no null columns.
- Each concrete class is independent → useful if subclasses are totally unrelated in data.
❌ Cons:
- Polymorphic queries are slow → require UNIONs.
- Data for shared fields is duplicated across subclass tables → denormalized.
- Schema changes (e.g., adding a base class field) require changing multiple tables.
📌 Key Takeaways
✅ TABLE_PER_CLASS creates one table per concrete class, no shared base table.
✅ Avoids nulls but causes duplication of base fields → leads to maintenance headaches.
✅ Polymorphic queries can be inefficient due to UNIONs.