5.2.1.2.2. Аннотации атрибутов
Аннотации атрибутов устанавливаются на соответствующие поля класса, за одним исключением: если требуется объявить неизменяемый (read only) неперсистентный атрибут foo
, то достаточно создать метод доступа getFoo()
и поместить на этот метод аннотацию @MetaProperty
.
- @CaseConversion
-
Применяет автоматическую конвертацию регистра к текстовым полям ввода, связанным с аннотированным атрибутом.
Параметры:
-
type
- тип конвертации:UPPER
(по умолчанию),LOWER
.
Пример:
@CaseConversion(type = ConversionType.UPPER) @Column(name = "COUNTRY_CODE") protected String countryCode;
-
- @Column
-
Определяет колонку БД, в которой будут храниться значения данного атрибута.
Параметры:
-
name
- имя колонки -
length
- (необязательный параметр, по умолчанию255
) - длина колонки. Используется также при формировании метаданных и, в конечном счете, может ограничивать максимальную длину вводимого текста в визуальных компонентах, работающих с данным атрибутом. Для отмены ограничения по длине атрибуту необходимо добавить аннотацию @Lob. -
nullable
- (необязательный параметр, по умолчаниюtrue
) - может ли атрибут содержатьnull
. При указанииnullable = false
JPA контролирует наличие значения поля при сохранении, кроме того, визуальные компоненты, работающие с данным атрибутом, могут сигнализировать пользователю о необходимости ввода значения.
-
- @Composition
-
Указывает на то, что связь является композицией - более тесным вариантом ассоциации. Это означает, что связанная сущность имеет смысл только как часть владеющей сущности, т.е. создается и удаляется вместе с ней.
Например, список пунктов в заказе (класс
Order
содержит коллекцию экземпляровItem
):@OneToMany(mappedBy = "order") @Composition protected List<Item> items;
Другой пример - one-to-one отношение:
@Composition @OneToOne(fetch = FetchType.LAZY) @JoinColumn(name = "DETAILS_ID") protected CustomerDetails details;
Указание для связи аннотации
@Composition
позволяет организовать в экранах редактирования специальный режим коммита источников данных, при котором изменения экземпляров детализирующей сущности сохраняются в базе данных только при коммите основной сущности. Подробнее см. Редактирование композитных сущностей.
- @Embedded
-
Определяет атрибут типа встраиваемой сущности, в свою очередь аннотированной
@Embeddable
.Пример:
@Embedded protected Address address;
- @EmbeddedParameters
-
По умолчанию ORM не создает экземпляр встроенной сущности если все ее атрибуты равны null в базе данных. Аннотацию
@EmbeddedParameters
можно использовать для указания того, что экземпляр всегда должен создаваться, например:@Embedded @EmbeddedParameters(nullAllowed = false) protected Address address;
- @Id
-
Указывает, что данный атрибут является первичным ключом сущности. Обычно эта аннотация присутствует на поле базового класса, такого как BaseUuidEntity. Использовать эту аннотацию в конкретном классе сущности необходимо только при наследовании от базового класса
BaseStringIdEntity
(то есть при создании сущности со строковым первичным ключом).
- @IgnoreUserTimeZone
-
Для атрибутов типа timestamp с аннотацией
@javax.persistence.Temporal.TIMESTAMP
заставляет платформу игнорировать часовой пояс пользователя, если он задан для текущей сессии.
- @JoinColumn
-
Используется для указания колонки БД, определяющей ассоциацию между сущностями. Наличие этой аннотации указывает, что данная сторона отношения является владеющей (owning).
Параметры:
-
name
- имя колонки
Пример:
@ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "CUSTOMER_ID") protected Customer customer;
-
- @JoinTable
-
Используется для указания таблицы связи на ведущей стороне
@ManyToMany
ассоциации.Параметры:
-
name
- имя таблицы связи -
joinColumns
- элемент@JoinColumn
, определяющий колонку таблицы связей, соответствующую первичному ключу ведущей стороны ассоциации (т.е. содержащей аннотацию@JoinTable
) -
inverseJoinColumns
- элемент@JoinColumn
, определяющий колонку таблицы связей, соответствующую первичному ключу ведомой стороны ассоциации
Пример атрибута
customers
классаGroup
, являющегося ведущей стороной ассоциации:@ManyToMany @JoinTable(name = "SALES_CUSTOMER_GROUP_LINK", joinColumns = @JoinColumn(name = "GROUP_ID"), inverseJoinColumns = @JoinColumn(name = "CUSTOMER_ID")) protected Set<Customer> customers;
Пример атрибута
groups
классаCustomer
, являющегося ведомой стороной этой же ассоциации:@ManyToMany(mappedBy = "customers") protected Set<Group> groups;
-
- @Lob
-
Указывает, что данный атрибут не имеет ограничений длины. Применяется совместно с аннотацией
@Column
. Если@Lob
указан, то длина, заданная в@Column
явно или по умолчанию, игнорируется.Пример:
@Column(name = "DESCRIPTION") @Lob private String description;
- @LocalizedValue
-
Служит для описания способа получения локализованного значения некоторого изменяющегося атрибута, которое возвращает метод
MessageTools.getLocValue()
.Параметры:
-
messagePack
- явное указание пакета, из которого будет взято локализованное сообщение, например,com.haulmont.cuba.core.entity
-
messagePackExpr
- выражение в терминах пути к атрибуту, хранящему имя пакета, из которого будет взято локализованное сообщение, напримерproc.messagesPack
. Путь начинается с атрибута текущей сущности.
Пример аннотации, означающей, что локализованное значение атрибута
state
будет взято из пакета, имя которого хранится в атрибутеmessagesPack
связанной сущностиproc
:@Column(name = "STATE") @LocalizedValue(messagePackExpr = "proc.messagesPack") protected String state; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "PROC_ID") protected Proc proc;
-
- @Lookup
-
Определяет тип просмотра ссылочных атрибутов.
Параметры:
-
type
- по умолчанию имеет значениеSCREEN
, при котором ссылки открываются через lookup-экран. ЗначениеDROPDOWN
позволяет открывать ссылки в виде выпадающего списка. Если за способ отображения выбранDROPDOWN
, Studio создаст options datasource для выпадающего списка при скаффолдинге экрана редактирования. Таким образом, параметр Lookup type необходимо задать ДО генерации экрана редактирования сущности. Кроме того, компонент Filter позволит пользователям выбирать параметры фильтрации также из выпадающего списка вместо lookup-экрана. -
actions
- определяет действия, которые будут использованы в компонентеPickerField
в составеFieldGroup
по умолчанию. Возможные значения:lookup
,clear
,open
.
@Lookup(type = LookupType.DROPDOWN, actions = {"open"}) @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "CUSTOMER_ID") protected Customer customer;
-
- @ManyToMany
-
Определяет атрибут-коллекцию ссылок на сущность с типом ассоциации много-ко-многим.
Ассоциация много-ко-многим всегда имеет ведущую сторону и может иметь обратную сторону - ведомую. На ведущей стороне указывается дополнительная аннотация
@JoinTable
, на ведомой стороне - параметрmappedBy
.Параметры:
-
mappedBy
- поле связанной сущности, определяющее ассоциацию с ведущей стороны. Необходимо указывать только на ведомой стороне. -
targetEntity
- тип связанной сущности. Необязательный параметр, если коллекция объявлена с использованием Java generics. -
fetch
- (необязательный параметр, по умолчаниюLAZY
) - определяет, будет ли JPA жадно загружать коллекцию связанных сущностей. Необходимо всегда оставлять значение по умолчаниюLAZY
, так как в CUBA-приложении политика загрузки связей определяется динамически на основе механизма представлений.
WarningИспользование параметра
cascade
аннотации не рекомендуется. Сущности, сохраняемые неявно при использовании такого объявления, будут пропущены некоторыми системными механизмами. В частности, бин EntityStates некорректно определяет для них состояние managed, а entity listeners не вызываются вообще. -
- @ManyToOne
-
Определяет атрибут-ссылку на сущность с типом ассоциации много-к-одному.
Параметры:
-
fetch
- (по умолчаниюEAGER
) параметр, определяющий, будет ли JPA жадно загружать ассоциированную сущность. Данный параметр всегда должен быть установлен в значениеLAZY
, так как в CUBA-приложении политика загрузки связей определяется динамически на основе механизма представлений. -
optional
- (необязательный параметр, по умолчаниюtrue
) - может ли атрибут содержатьnull
. При указанииoptional = false
JPA контролирует наличие ссылки при сохранении, кроме того, визуальные компоненты, работающие с данным атрибутом, могут сигнализировать пользователю о необходимости ввода значения.
Например, несколько экземпляров
Order
(заказов) ссылаются на один экземплярCustomer
(покупателя), в этом случае классOrder
должен содержать следующее объявление:@ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "CUSTOMER_ID") protected Customer customer;
WarningИспользование параметра
cascade
аннотации не рекомендуется. Сущности, сохраняемые неявно при использовании такого объявления, будут пропущены некоторыми системными механизмами. В частности, бин EntityStates некорректно определяет для них состояние managed, а entity listeners не вызываются вообще. -
- @MetaProperty
-
Указывает, что данный атрибут должен быть включен в метаданные. Данная аннотация может быть установлена как на поле класса, так и на метод доступа, в случае отсутствия соответствующего атрибуту поля.
Данная аннотация не обязательна для полей, снабженных следующими аннотациями пакета
javax.persistence
:@Column
,@OneToOne
,@OneToMany
,@ManyToOne
,@ManyToMany
,@Embedded
. Такие поля отражаются в метаданных автоматически. Поэтому@MetaProperty
в основном применяется для определения неперсистентных атрибутов сущностей.Параметры (опционально):
-
mandatory
- может ли атрибут содержатьnull
. При указанииmandatory = true
визуальные компоненты, работающие с данным атрибутом, могут сигнализировать пользователю о необходимости ввода значения. -
datatype
- явно задает datatype, чтобы переопределить datatype задаваемый Java-типом атрибута. -
related
- задает массив связанных персистентных атрибутов, которые должны быть загружены из БД, если данный атрибут включен во view.
Пример использования для поля:
@Transient @MetaProperty protected String token;
Пример использования для метода:
@MetaProperty public String getLocValue() { if (!StringUtils.isBlank(messagesPack)) { return AppBeans.get(Messsages.class).getMessage(messagesPack, value); } else { return value; } }
-
- @NumberFormat
-
Задает формат атрибута типа
Number
(это может бытьBigDecimal
,Integer
,Long
илиDouble
). Значения такого атрибута будут форматироваться в пользовательском интерфейсе в соответствии с указанными параметрами аннотации:-
pattern
- паттерн форматирования, задается по правилам, описанным в DecimalFormat. -
decimalSeparator
- символ, используемый в качестве разделителя целой и дробной части (опционально). -
groupingSeparator
- символ, используемый в качестве разделителя групп разрядов (optional).
Если
decimalSeparator
и/илиgroupingSeparator
не указаны, фреймворк использует соответствующие значения из format strings для локали текущего пользователя. При форматировании без учета локали в этом случае используются символы из системной локали сервера.Примеры:
@Column(name = "PRECISE_NUMBER", precision = 19, scale = 4) @NumberFormat(pattern = "0.0000") protected BigDecimal preciseNumber; @Column(name = "WEIRD_NUMBER", precision = 19, scale = 4) @NumberFormat(pattern = "#,##0.0000", decimalSeparator = "_", groupingSeparator = "`") protected BigDecimal weirdNumber; @Column(name = "SIMPLE_NUMBER") @NumberFormat(pattern = "#") protected Integer simpleNumber; @Column(name = "PERCENT_NUMBER", precision = 19, scale = 4) @NumberFormat(pattern = "#%") protected BigDecimal percentNumber;
-
- @OnDelete
-
Определяет политику обработки связи в случае мягкого удаления сущности, содержащей данный атрибут. См. Мягкое удаление.
Пример:
@OneToMany(mappedBy = "group") @OnDelete(DeletePolicy.CASCADE) private Set<Constraint> constraints;
- @OnDeleteInverse
-
Определяет политику обработки связи в случае мягкого удаления сущности с обратной стороны ассоциации. См. Мягкое удаление.
Пример:
@ManyToOne @JoinColumn(name = "DRIVER_ID") @OnDeleteInverse(DeletePolicy.DENY) private Driver driver;
- @OneToMany
-
Определяет атрибут-коллекцию ссылок на сущность с типом ассоциации один-ко-многим.
Параметры:
-
mappedBy
- поле связанной сущности, определяющее ассоциацию -
targetEntity
- тип связанной сущности. Необязательный параметр, если коллекция объявлена с использованием Java generics. -
fetch
- (необязательный параметр, по умолчаниюLAZY
) - определяет, будет ли JPA жадно загружать коллекцию связанных сущностей. Необходимо всегда оставлять значение по умолчаниюLAZY
, так как в CUBA-приложении политика загрузки связей определяется динамически на основе механизма представлений. -
cascade
- (необязательный параметр, по умолчанию{}
) - каскадирование операций определяет, какие операции над сущностью должны быть применены к ассоциированным сущностям. Каскадирование на данном уровне не рекомендуется использовать.
Например, несколько экземпляров
Item
(пунктов заказа) ссылаются на один экземплярOrder
(заказ) с помощью@ManyToOne
поляItem.order
, в этом случае классOrder
может содержать коллекцию экземпляровItem
:@OneToMany(mappedBy = "order") protected Set<Item> items;
WarningИспользование параметра
cascade
аннотации не рекомендуется. Сущности, сохраняемые неявно при использовании такого объявления, будут пропущены некоторыми системными механизмами. В частности, бин EntityStates некорректно определяет для них состояние managed, а entity listeners не вызываются вообще. ПараметрorphanRemoval
не принимает во внимание механизм мягкого удаления. -
- @OneToOne
-
Определяет атрибут-ссылку на сущность с типом ассоциации один-к-одному.
Параметры:
-
fetch
- (по умолчаниюEAGER
) параметр, определяющий, будет ли JPA жадно загружать ассоциированную сущность. Данный параметр всегда должен быть установлен в значениеLAZY
, так как в CUBA-приложении политика загрузки связей определяется динамически на основе механизма представлений. -
mappedBy
- поле связанной сущности, определяющее ассоциацию. Требуется устанавливать только на ведомой стороне ассоциации. -
optional
- (необязательный параметр, по умолчаниюtrue
) - может ли атрибут содержатьnull
. При указанииoptional = false
JPA контролирует наличие ссылки при сохранении, кроме того, визуальные компоненты, работающих с данным атрибутом, могут сигнализировать пользователю о необходимости ввода значения.
Пример ведущей стороны ассоциации, класс
Driver
:@OneToOne(fetch = FetchType.LAZY) @JoinColumn(name = "CALLSIGN_ID") protected DriverCallsign callsign;
Пример ведомой стороны ассоциации, класс
DriverCallsign
:@OneToOne(fetch = FetchType.LAZY, mappedBy = "callsign") protected Driver driver;
-
- @OrderBy
-
Определяет порядок элементов в атрибуте-коллекции на момент извлечения из базы данных. Данную аннотацию необходимо задавать для упорядоченных коллекций, таких как
List
илиLinkedHashSet
для получения предсказуемого порядка следования элементов.Параметры:
-
value
- строка, определяющая порядок, в формате:orderby_list::= orderby_item [,orderby_item]* orderby_item::= property_or_field_name [ASC | DESC]
Пример:
@OneToMany(mappedBy = "user") @OrderBy("createTs") protected List<UserRole> userRoles;
-
- @Temporal
-
Для атрибута типа
java.util.Date
уточняет тип хранимого значения: дата, время или дата+время.Параметры:
-
value
- тип хранимого значения:DATE
,TIME
,TIMESTAMP
Пример:
@Column(name = "START_DATE") @Temporal(TemporalType.DATE) protected Date startDate;
-
- @Transient
-
Указывает, что данное поле не хранится в БД, т.е. является неперсистентным.
Поля поддерживаемых JPA типов (см. http://docs.oracle.com/javaee/7/api/javax/persistence/Basic.html) по умолчанию являются персистентными, поэтому аннотация
@Transient
обязательна для объявления неперсистентного атрибута такого типа.Для включения
@Transient
атрибута в метаданные, необходимо также указать аннотацию@MetaProperty
.
- @Version
-
Указывает, что данное поле хранит версию для поддержки оптимистичной блокировки сущностей.
Применение такого поля необходимо при реализации классом сущности интерфейса
Versioned
(базовый классStandardEntity
уже содержит такое поле).Пример:
@Version @Column(name = "VERSION") private Integer version;