Что такое Embeddable-класс в JPA (Hibernate)?

«Что такое Embeddable-класс в JPA (Hibernate)?» — вопрос из категории Hibernate, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Embeddable-класс (встраиваемый класс) в JPA — это класс, помеченный аннотацией @Embeddable, который представляет собой группу полей, логически принадлежащих сущности, но не являющихся самостоятельной сущностью. Его поля сохраняются в таблице родительской сущности.

Зачем это нужно? Для нормализации объектной модели без создания лишних таблиц и JOIN-ов в БД.

Пример: Группировка адреса внутри сущности Person.

  1. Создаем Embeddable-класс Address:

    @Embeddable
    public class Address {
        private String city;
        private String street;
        private String zipCode;
        // Конструкторы, геттеры, сеттеры
    }

    Этот класс не имеет @Id, @Entity и своей таблицы в БД.

  2. Используем его в сущности Person:

    @Entity
    public class Person {
        @Id
        private Long id;
        private String name;
    
        @Embedded
        private Address homeAddress;
    
        @Embedded
        @AttributeOverrides({
            @AttributeOverride(name = "city", column = @Column(name = "work_city")),
            @AttributeOverride(name = "street", column = @Column(name = "work_street"))
        })
        private Address workAddress;
        // Геттеры, сеттеры
    }

    В таблице Person появятся колонки: city, street, zip_code, work_city, work_street.

Ключевые особенности:

  • Нет отдельной таблицы: Все поля Address хранятся в таблице Person.
  • Нет собственного идентификатора: Не может существовать отдельно от сущности-владельца.
  • Может использоваться в нескольких сущностях: Класс Address можно встроить в Company, Office и т.д.
  • Поддерживает переопределение колонок: Аннотация @AttributeOverrides позволяет задать имена колонок для каждого встраивания.
  • Может содержать другие @Embeddable объекты: Поддерживается вложенность.

Использование: Для типов-значений (Value Objects), таких как Деньги (Money с полями amount и currency), Геопозиция (Coordinates), Полное имя (FullName) и т.п.