Карта / JPA / Hibernate / Стратегии наследования

Стратегии наследования

Когда у Entity-классов есть иерархия наследования (EmployeeManager, Developer), нужно решить, как это отразить в реляционных таблицах — у БД ведь нет понятия “наследование”, только таблицы со столбцами.

SINGLE_TABLE — одна таблица на всю иерархию, с дополнительным столбцом-дискриминатором:

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "employee_type")
class Employee { ... }

@Entity
@DiscriminatorValue("MANAGER")
class Manager extends Employee { private int teamSize; }

Все поля (и Employee, и Manager, и Developer) — в одной таблице, лишние поля для каждой конкретной строки просто NULL. Это стратегия по умолчанию.

Копнуть глубже

Три стратегии — компромисс скорость/чистота:

СтратегияСтруктураПлюсыМинусы
SINGLE_TABLEодна таблицабыстрые запросы, нет JOINмного NULL, “грязная” таблица
JOINEDтаблица на каждый класс, связаны через idчистая нормализованная структуранужен JOIN для полных данных
TABLE_PER_CLASSотдельная таблица на каждый класс целикомнезависимые таблицыдублирование общих полей, сложные запросы по всей иерархии
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
class Employee { @Id Long id; String name; }

@Entity
class Manager extends Employee { int teamSize; }   // отдельная таблица Manager(id, team_size)

На практике SINGLE_TABLE выбирают чаще всего — простота и скорость запросов обычно важнее идеальной нормализации, особенно когда иерархия не слишком “разнородная” по набору полей.

🎤 Закрыл тему, если можешь объяснить:
• зачем нужны стратегии наследования и что такое дискриминатор;
• плюсы и минусы SINGLE_TABLE и JOINED (если дошёл до 2-го слоя).