Почему класс Entity в JPA/Hibernate не может быть объявлен как final?

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

Ответ

Класс Entity не может быть final, потому что JPA-провайдеры (например, Hibernate) используют динамическое проксирование для реализации ключевых функций, таких как ленивая загрузка (Lazy Loading). Прокси создаются путём наследования от класса сущности, что невозможно, если класс объявлен финальным.

Почему это важно:

  • Ленивая загрузка: Для ассоциаций с fetch = LAZY Hibernate подставляет прокси-объект. Если класс final, наследование для создания прокси невозможно.
  • Улучшения производительности: Прокси также используются для отслеживания изменений и управления кэшем второго уровня.

Пример, который вызовет проблему:

@Entity
public final class User { // ОШИБКА: final класс
    @Id
    private Long id;
    @OneToMany(fetch = FetchType.LAZY)
    private List<Order> orders; // Ленивая загрузка не будет работать
}

Решение: Всегда оставляйте классы сущностей нефинальными и обеспечивайте для них конструктор по умолчанию (без аргументов).