Нужно ли добавлять поле type в entity для базы данных
Что проверяют
Понимаете ли вы, откуда в таблице вообще берётся колонка с типом: это дискриминатор подтипов, справочное значение или попытка заменить нормальную модель одной универсальной таблицей. За вопросом почти всегда стоит проверка знания наследования в JPA.
Как отвечать
Сначала разделить три разных случая.
- Это дискриминатор иерархии. Своё поле заводить не нужно: при стратегии
SINGLE_TABLEHibernate сам заводит колонку из@DiscriminatorColumnи заполняет её. Если значение нужно читать кодом, поле маппится на ту же колонку сinsertable = false, updatable = false, иначе получится два маппинга одной колонки. - Это конечный набор категорий самой сущности. Тогда это обычное поле с
@Enumerated(EnumType.STRING)плюс ограничение на стороне базы. - Это признак, по которому в одной таблице лежат сущности с разным набором обязательных полей. Здесь поле лечит симптом: при
SINGLE_TABLEколонки подтипов обязаны быть nullable, иNOT NULLвы уже не поставите.
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "type")
public abstract class Payment { }Хорошо добавить, что выбор стратегии это компромисс: одна таблица быстрее на чтении и не требует соединений, JOINED даёт нормальную схему и настоящие ограничения ценой join на каждую выборку.
Где спотыкаются
Оставляют @Enumerated без параметра. По умолчанию это ORDINAL, в базе лежат порядковые номера, и вставка нового значения в середину перечисления молча переставляет смысл уже записанных строк.
Хранят тип свободной строкой без справочника и без CHECK. Через полгода в колонке живут значения с опечатками и в разном регистре, а фильтры по типу начинают терять строки.
Путают дискриминатор с бизнес-полем и меняют его обычным апдейтом. Для Hibernate это смена класса объекта: такого он не ждёт, и в кэше первого уровня остаётся экземпляр прежнего типа.