[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"question-hibernate-strategii-nasledovaniya-v-hibernate":3},{"id":4,"slug":5,"topicId":6,"topicSlug":7,"topicName":8,"topicEmoji":9,"question":10,"answer":11,"codeLang":12,"codeSrc":12,"important":12,"commonMistakes":12,"modernUsage":12,"difficulty":13,"tags":14,"related":18,"progress":19,"seo":20},1038,"strategii-nasledovaniya-v-hibernate",19,"hibernate","Hibernate","🐻","Стратегии наследования в Hibernate","JPA определяет три стратегии маппинга иерархии наследования в реляционные таблицы.\n\n### Сравнение стратегий\n\n| Критерий | SINGLE_TABLE | JOINED | TABLE_PER_CLASS |\n|----------|-------------|--------|-----------------|\n| Производительность полиморфных запросов | Лучшая (одна таблица) | Средняя (JOIN) | Худшая (UNION) |\n| Нормализация | Низкая (NULL-столбцы) | Высокая | Средняя |\n| NOT NULL ограничения | Невозможны для подклассов | Возможны | Возможны |\n| Добавление подкласса | Простое (новый столбец) | Новая таблица + FK | Новая таблица |\n\n### SINGLE_TABLE (одна таблица)\n\n```java\n@Entity\n@Inheritance(strategy = InheritanceType.SINGLE_TABLE)\n@DiscriminatorColumn(name = \"type\", discriminatorType = DiscriminatorType.STRING)\npublic abstract class Payment {\n    @Id @GeneratedValue\n    private Long id;\n    private BigDecimal amount;\n}\n\n@Entity\n@DiscriminatorValue(\"CARD\")\npublic class CardPayment extends Payment {\n    private String cardNumber;  \u002F\u002F null для других типов\n}\n\n@Entity\n@DiscriminatorValue(\"CASH\")\npublic class CashPayment extends Payment {\n    private String currency;\n}\n```\n\nТаблица: `payment(id, type, amount, card_number, currency)` — все поля в одной таблице, неиспользуемые = NULL.\n\n### JOINED (таблица на класс)\n\n```java\n@Entity\n@Inheritance(strategy = InheritanceType.JOINED)\npublic abstract class Payment {\n    @Id @GeneratedValue\n    private Long id;\n    private BigDecimal amount;\n}\n\n@Entity\npublic class CardPayment extends Payment {\n    private String cardNumber;\n}\n```\n\nТаблицы: `payment(id, amount)` + `card_payment(id, card_number)` — данные разнесены, связаны по PK\u002FFK.\n\n### TABLE_PER_CLASS (таблица на конкретный класс)\n\n```java\n@Entity\n@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)\npublic abstract class Payment {\n    @Id @GeneratedValue(strategy = GenerationType.TABLE)\n    private Long id;\n    private BigDecimal amount;\n}\n```\n\nТаблицы: `card_payment(id, amount, card_number)`, `cash_payment(id, amount, currency)` — дублирование общих полей.\n\n### Важное\n\n- SINGLE_TABLE — по умолчанию и самая производительная; идеальна когда подклассов немного\n- JOINED — когда важна нормализация и NOT NULL ограничения; ценой производительности на JOIN\n- TABLE_PER_CLASS — используется редко; полиморфные запросы требуют UNION ALL\n- `@DiscriminatorColumn` — указывает столбец-дискриминатор для SINGLE_TABLE и JOINED\n\n### Частые ошибки\n\n- TABLE_PER_CLASS с полиморфными запросами — `findAll()` для базового класса генерирует UNION ALL по всем таблицам\n- SINGLE_TABLE с NOT NULL — поля подклассов не могут быть NOT NULL (они null для других типов)\n- Глубокая иерархия с JOINED — каждый уровень наследования = дополнительный JOIN\n\n### Как используется в 2026\n\n- SINGLE_TABLE — стандартный выбор для большинства случаев\n- Альтернатива наследованию: композиция через `@Embedded` или паттерн «тип + JSON-данные»\n- В DDD: наследование Entity используется для Value Objects и Aggregate Roots с ограниченной иерархией\n\n> **На собеседовании:** назовите три стратегии и их трейд-оффы. SINGLE_TABLE — быстро, но NULL-столбцы. JOINED — нормализовано, но JOIN-ы. TABLE_PER_CLASS — редко используется из-за UNION ALL. Покажите, что в реальных проектах чаще выбирают SINGLE_TABLE, а глубокое наследование заменяют композицией.","","middle",[15,16,17,7],"mapping","inheritance","jpa",[],null,{"title":21,"description":22,"ogTitle":23,"ogDescription":24,"keywords":25,"schemaAnswer":33,"featuredSnippetReady":34},"Стратегии наследования в Hibernate — Gymterview","Три стратегии JPA: SINGLE_TABLE (одна таблица), JOINED (таблица на класс), TABLE_PER_CLASS (таблица на конкретный класс). Сравнение и примеры кода.","Стратегии наследования: SINGLE_TABLE vs JOINED vs TABLE_PER_CLASS — Gymterview","Три стратегии маппинга наследования в JPA. SINGLE_TABLE — быстро, но NULL-столбцы. JOINED — нормализовано. TABLE_PER_CLASS — редко используется.",[26,27,28,29,30,31,32,8],"наследование Hibernate","SINGLE_TABLE","JOINED","TABLE_PER_CLASS","InheritanceType","DiscriminatorColumn","JPA","JPA определяет 3 стратегии: SINGLE_TABLE — все подклассы в одной таблице с дискриминатором (быстрые полиморфные запросы, но NULL-столбцы). JOINED — таблица на каждый класс, связь по PK\u002FFK (нормализовано, но JOIN при запросах). TABLE_PER_CLASS — отдельная таблица для каждого конкретного класса (UNION ALL при полиморфных запросах). SINGLE_TABLE — стандартный выбор.",true]