Маппинг Enum
@Enumerated
@Enumerated(EnumType.STRING)
@Column(nullable = false)
private OrderStatus status;ORDINALхранит порядковый номер. Перестановка или вставка значения меняет смысл существующих строк.STRINGхранит имя константы. Безопаснее к порядку, но переименование требует миграции.
EnumType.STRING обычно лучше, однако имя Java-константы становится частью формата данных.
Стабильный код через converter
Если БД должна хранить независимый код, используется AttributeConverter:
public enum Status {
NEW("N"), DONE("D");
private final String code;
}
@Converter(autoApply = true)
public class StatusConverter
implements AttributeConverter<Status, String> {
public String convertToDatabaseColumn(Status value) {
return value == null ? null : value.code();
}
public Status convertToEntityAttribute(String code) {
return code == null ? null : Status.fromCode(code);
}
}Не следует одновременно применять к одному атрибуту @Enumerated и converter.
Ограничения
БД должна отвергать неизвестные значения: через CHECK, справочник или подходящий нативный тип. При чтении неизвестного кода приложение должно падать заметно, а не тихо подменять его значением по умолчанию.
Вопросы для повторения
- Почему
ORDINALопасен? Порядок enum становится контрактом сохранённых данных. - Достаточно ли
STRINGдля стабильности? Нет, переименование константы меняет контракт. - Когда нужен converter? Когда формат БД должен быть независим от имени Java enum.
- Как добавить новое значение безопасно? Сначала расширить допустимый формат/читателей, затем начать запись нового кода.
Связано: Маппинг Hibernate, Аннотация Column.