Колонка-enum, замапленная через @Enumerated(EnumType.STRING), хранит в БД строку с именем значения. Если убрать значение из Java-enum, а в таблице остались строки с этим именем — Hibernate при чтении (гидратации) сущности падает:

IllegalArgumentException: No enum constant <EnumClass>.<OLD_VALUE>

Сущность перестаёт читаться, и ломается всё, что её грузит из БД.

Правило

Перед удалением значения из enum — мигрировать все строки в таблице (во всех средах: dev/stage/prod) на новое допустимое значение. Удалять значение из кода только после того, как в БД не осталось строк со старым именем.

Подводные камни миграции

  • Не матчить по хардкод-id. UPDATE ... WHERE id = '<...>' чинит только перечисленные строки. Строки, созданные приложением (случайные id), останутся со старым значением. Матчить по содержимому: UPDATE ... SET type = 'NEW' WHERE type = 'OLD'.
  • Проверять все среды. Значение, отсутствующее в dev (где данные — seed), может остаться в stage/prod, где строки заводились приложением или вручную.

Почему именно так

@Enumerated(STRING) (в отличие от ORDINAL) хранит имя константы, а не порядковый номер — это устойчиво к перестановке значений, но строго к их набору: маппинг строки в enum идёт через Enum.valueOf, который бросает исключение на неизвестном имени.

Похожий класс гоч маппинга — Дублирование значений при использовании @ElementCollection и @OneToMany.