Какими свойствами должен обладать класс, чтобы быть Entity в JPA?

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

Ответ

Класс, чтобы быть Entity в JPA (Java Persistence API), должен соответствовать следующим обязательным требованиям:

  1. Аннотация @Entity — обязательная метка класса как сущности.
  2. Пустой конструктор (может быть protected) — требуется для рефлексии и создания прокси.
  3. Класс не должен быть final — иначе Hibernate не сможет создать прокси для ленивой загрузки.
  4. Наличие первичного ключа — поле с аннотацией @Id (может быть составным через @EmbeddedId).
  5. Поля должны быть private/protected с геттерами/сеттерами — для доступа через отражение.
  6. Методы доступа (геттеры/сеттеры) не должны быть final — по той же причине, что и класс.

Пример Entity-класса:

@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "user_name", nullable = false, length = 100)
    private String name;

    // Обязательный пустой конструктор
    public User() {}

    // Геттеры и сеттеры (не final)
    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
}

Почему эти правила важны:

  • Пустой конструктор и не-final класс/методы нужны для работы механизма проксирования Hibernate, который реализует ленивую загрузку (Lazy Loading).
  • Приватные поля с геттерами/сеттерами обеспечивают инкапсуляцию и дают Hibernate контролируемый доступ к данным через отражение.
  • @Id однозначно идентифицирует запись в базе данных.