Перейти к основному содержимому

JPA @Embedded и @Embeddable

· 3 мин. чтения

1. Обзор

В этом руководстве мы увидим, как можно сопоставить одну сущность, содержащую встроенные свойства, с одной таблицей базы данных.

Итак, для этой цели мы будем использовать аннотации @Embeddable и @Embedded , предоставляемые Java Persistence API (JPA) .

2. Контекст модели данных

Прежде всего, давайте определим таблицу с именем company .

В таблице компаний будет храниться основная информация, такая как название компании, адрес и телефон, а также информация о контактном лице:

public class Company {

private Integer id;

private String name;

private String address;

private String phone;

private String contactFirstName;

private String contactLastName;

private String contactPhone;

// standard getters, setters
}

Однако контактное лицо, похоже, должно быть абстрагировано в отдельный класс. Проблема в том, что мы не хотим создавать отдельную таблицу для этих деталей. Итак, давайте посмотрим, что мы можем сделать.

3. @Встраиваемый

JPA предоставляет аннотацию @Embeddable , чтобы объявить, что класс будет внедрен другими объектами.

Давайте определим класс для абстрагирования сведений о контактном лице:

@Embeddable
public class ContactPerson {

private String firstName;

private String lastName;

private String phone;

// standard getters, setters
}

4. @Встроенный

Аннотация JPA @Embedded используется для встраивания типа в другой объект.

Давайте теперь изменим наш класс Company . Мы добавим аннотации JPA, а также изменим использование ContactPerson вместо отдельных полей:

@Entity
public class Company {

@Id
@GeneratedValue
private Integer id;

private String name;

private String address;

private String phone;

@Embedded
private ContactPerson contactPerson;

// standard getters, setters
}

В результате у нас есть наша сущность Company , содержащая данные контактного лица и сопоставленная с одной таблицей базы данных.

У нас все еще есть еще одна проблема, и это то, как JPA будет отображать эти поля в столбцы базы данных.

5. Переопределение атрибутов

Дело в том, что наши поля назывались такими вещами, как contactFirstName в нашем исходном классе Company , а теперь firstName в нашем классе ContactPerson . Таким образом, JPA захочет сопоставить их с contact_first_name и first_name соответственно.

Помимо того, что это далеко не идеально, это на самом деле сломает нас с нашей теперь дублированной телефонной колонкой.

Итак, мы можем использовать @AttributeOverrides и @AttibuteOverride , чтобы переопределить свойства столбца нашего встроенного типа.

Давайте добавим это в поле ContactPerson в нашей сущности Company :

@Embedded
@AttributeOverrides({
@AttributeOverride( name = "firstName", column = @Column(name = "contact_first_name")),
@AttributeOverride( name = "lastName", column = @Column(name = "contact_last_name")),
@AttributeOverride( name = "phone", column = @Column(name = "contact_phone"))
})
private ContactPerson contactPerson;

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

6. Заключение

В этом руководстве мы настроили объект с некоторыми встроенными атрибутами и сопоставили их с той же таблицей базы данных, что и объемлющий объект. Для этого мы использовали аннотации @Embedded , @Embeddable , @AttributeOverrides и @AttributeOverride , предоставляемые Java Persistence API.

Как всегда, исходный код примера доступен на GitHub .