4.2.1.2.2. Аннотации атрибутов

Аннотации атрибутов устанавливаются на соответствующие поля класса, за одним исключением: если требуется объявить неизменяемый (read only) неперсистентный атрибут foo, то достаточно создать метод доступа getFoo() и поместить на этот метод аннотацию @MetaProperty.

@javax.persistence.Transient

Указывает, что данное поле не хранится в БД, т.е. является неперсистентным.

Поля поддерживаемых JPA типов (см. http://docs.oracle.com/javaee/5/api/javax/persistence/Basic.html) по умолчанию являются персистентными, поэтому аннотация @Transient обязательна для объявления неперсистентного атрибута такого типа.

Для включения @Transient атрибута в метаданные, необходимо также указать аннотацию @MetaProperty .

@org.apache.openjpa.persistence.Persistent

Указывает, что данное поле хранится в БД, т.е. является персистентным.

Данная аннотация требуется только для нестандартного для JPA типа поля, платформа на данный момент поддерживает один такой тип - java.util.UUID. Таким образом, @Persistent требуется только в одном случае - при объявлении персистентного поля типа UUID.

@javax.persistence.Column

Определяет колонку БД, в которой будут храниться значения данного атрибута.

Параметры:

  • name - имя колонки

  • length - (необязательный параметр, по умолчанию 255) - длина колонки. Используется также при формировании метаданных и, в конечном счете, может ограничивать максимальную длину вводимого текста в визуальных компонентах, работающих с данным атрибутом. Для отмены ограничения по длине атрибуту необходимо добавить аннотацию @Lob.

  • nullable - (необязательный параметр, по умолчанию true) - может ли атрибут содержать null. При указании nullable = false JPA контролирует наличие значения поля при сохранении, кроме того, визуальные компоненты, работающие с данным атрибутом, могут сигнализировать пользователю о необходимости ввода значения.

@javax.persistence.Id

Указывает, что данный атрибут является первичным ключом сущности. Обычно эта аннотация присутствует на поле базового класса, такого как BaseUuidEntity. Использовать эту аннотацию в конкретном классе сущности необходимо только при наследовании от базового класса BaseStringIdEntity (то есть при создании сущности со строковым первичным ключом).

@javax.persistence.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;
@javax.persistence.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;
@javax.persistence.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;
@javax.persistence.ManyToMany

Определяет атрибут-коллекцию ссылок на сущность с типом ассоциации много-ко-многим.

Ассоциация много-ко-многим всегда имеет ведущую сторону и может иметь обратную сторону - ведомую. На ведущей стороне указывается дополнительная аннотация @JoinTable, на ведомой стороне - параметр mappedBy.

Параметры:

  • mappedBy - поле связанной сущности, определяющее ассоциацию с ведущей стороны. Необходимо указывать только на ведомой стороне.

  • targetEntity - тип связанной сущности. Необязательный параметр, если коллекция объявлена с использованием Java generics.

  • fetch - (необязательный параметр, по умолчанию LAZY) - определяет, будет ли JPA жадно загружать коллекцию связанных сущностей. Необходимо всегда оставлять значение по умолчанию LAZY, так как в CUBA-приложении политика загрузки связей определяется динамически на основе механизма представлений.

@javax.persistence.JoinColumn

Используется для указания колонки БД, определяющей ассоциацию между сущностями.

Параметры:

  • name - имя колонки

Пример:

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "CUSTOMER_ID")
protected Customer customer;
@javax.persistence.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;
@javax.persistence.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;
@javax.persistence.Embedded

Определяет атрибут типа встраиваемой сущности, в свою очередь аннотированной @Embeddable.

Пример:

@Embedded
protected Address address;
@javax.persistence.Temporal

Для атрибута типа java.util.Date уточняет тип хранимого значения: дата, время или дата+время.

Параметры:

  • value - тип хранимого значения: DATE, TIME, TIMESTAMP

Пример:

@Column(name = "START_DATE")
@Temporal(TemporalType.DATE)
protected Date startDate;
@javax.persistence.Version

Указывает, что данное поле хранит версию для поддержки оптимистичной блокировки сущностей.

Применение такого поля необходимо при реализации классом сущности интерфейса Versioned (базовый класс StandardEntity уже содержит такое поле).

Пример:

@Version
@Column(name = "VERSION")
private Integer version;
@javax.persistence.Lob

Указывает, что данный атрибут не имеет ограничений длины. Применяется совместно с аннотацией @Column. Если @Lob указан, то длина, заданная в @Column явно или по умолчанию, игнорируется.

Пример:

@Column(name = "DESCRIPTION")
@Lob
private String description;
@MetaProperty

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

Данная аннотация не обязательна для полей, снабженных следующими аннотациями пакета javax.persistence: @Column, @OneToOne, @OneToMany, @ManyToOne, @ManyToMany, @Embedded. Такие поля отражаются в метаданных автоматически. Поэтому @MetaProperty в основном применяется для определения неперсистентных атрибутов сущностей.

Параметры:

  • mandatory - (необязательный параметр, по умолчанию false) - может ли атрибут содержать null. При указании mandatory = true визуальные компоненты, работающие с данным атрибутом, могут сигнализировать пользователю о необходимости ввода значения.

Пример использования для поля:

@Transient
@MetaProperty
protected String token;

Пример использования для метода:

@MetaProperty
public String getLocValue() {
  if (!StringUtils.isBlank(messagesPack)) {
      return AppBeans.get(Messsages.class).getMessage(messagesPack, value);
  } else {
      return value;
  }
}
@OnDelete

Определяет политику обработки связи в случае мягкого удаления сущности, содержащей данный атрибут. См. Раздел 4.2.1.4, «Мягкое удаление»

Пример:

@OneToMany(mappedBy = "group")
@OnDelete(DeletePolicy.CASCADE)
private Set<Constraint> constraints;
@OnDeleteInverse

Определяет политику обработки связи в случае мягкого удаления сущности с обратной стороны ассоциации. См. Раздел 4.2.1.4, «Мягкое удаление»

Пример:

@ManyToOne
@JoinColumn(name = "DRIVER_ID")
@OnDeleteInverse(DeletePolicy.DENY)
private Driver driver;
@Composition

Указывает на то, что связь является композицией - более тесным вариантом ассоциации. Это означает, что связанная сущность имеет смысл только как часть владеющей сущности, т.е. создается и удаляется вместе с ней.

Например, список пунктов в заказе (класс Order содержит коллекцию экземпляров Item):

@OneToMany(mappedBy = "order")
@Composition
protected List<Item> items;

Указание для связи аннотации @Composition позволяет организовать в экранах редактирования специальный режим коммита источников данных, при котором изменения экземпляров детализирующей сущности сохраняются в базе данных только при коммите основной сущности. Подробнее см. Раздел 5.8.3, «Редактирование композитных сущностей».

@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;
@IgnoreUserTimeZone

Для атрибутов типа timestamp с аннотацией @javax.persistence.Temporal.TIMESTAMP заставляет платформу игнорировать часовой пояс пользователя, если он задан для текущей сессии.