Skip to content

Latest commit

 

History

History
37 lines (22 loc) · 4.74 KB

File metadata and controls

37 lines (22 loc) · 4.74 KB
Атрибуты типа enum

В стандартном варианте использования JPA для атрибутов типа enum в базе данных хранится целое число, получаемое методом ordinal() этого перечисления. Такой подход может привести к следующим проблемам при эксплуатации и развитии системы:

  • при появлении в БД значения, не равного ни одному ordinal значению перечисления, экземпляр сущности нельзя загрузить вообще;

  • невозможно ввести новое значение между имеющимися, что актуально при использовании сортировки по значению перечисления (order by).

Чтобы решить эти проблемы, в подходе CUBA предлагается отвязать значение, хранимое в БД, от ordinal перечисления. Для этого необходимо поле класса сущности объявлять с типом, хранимым в БД (Integer или String), а методы доступа (getter / setter) создавать для типа самого перечисления.

Например:

link:../../../../../source/common/enum_1.java[role=include]

При этом сам класс перечисления может выглядеть следующим образом:

link:../../../../../source/common/enum_2.java[role=include]

Для правильного отражения в метаданных класс перечисления, используемый в качестве типа атрибута сущности, должен реализовывать интерфейс EnumClass.

Как видно из примеров, для атрибута grade в БД хранится значение типа Integer, задаваемое полем id перечисления CustomerGrade, а конкретно 10, 20 или 30. В то же время прикладной код и метаданные работают с самим типом CustomerGrade через методы доступа, которые и осуществляют конвертацию.

При наличии в поле БД значения, не соответствующего ни одному значению перечисления, метод getGrade() просто вернет null. Для ввода нового значения, например, HIGHER, между HIGH и PREMIUM, достаточно добавить это значение в перечисление с идентификатором 15, при этом сортировка по полю Customer.grade останется верной.

Тип поля Integer удобно использовать в случаях, когда необходим упорядоченный список констант, подлежащий сортировке, например, в запросах JPQL и SQL (>, <, >=, , order by), кроме того, он имеет незначительное преимущество перед String в плане производительности формата хранения и занимаемого места. С другой стороны, значения типа Integer сами по себе неочевидны и могут затруднять отладку и интерпретацию результатов запросов, они неудобны в работе с голыми данными и сериализованными форматами. Если отношение упорядочения между константами не требуется, удобнее использовать тип String.

Перечисления могут быть созданы в CUBA Studio в секции Data Model > New > Enumeration. Чтобы использовать перечисление в качестве атрибута сущности, в редакторе атрибута нужно выбрать ENUM в поле Attribute type и класс перечисления в поле Type. Значениям перечисления могут быть сопоставлены локализованные названия для отображения в пользовательском интерфейсе приложения.