Что такое JPA и Hibernate
Что проверяют
Различаете ли вы спецификацию и реализацию и понимаете ли, что делает контекст персистентности.
Как отвечать
JPA это спецификация (сейчас jakarta.persistence): описывает аннотации (@Entity, @Id, @OneToMany), интерфейс EntityManager, язык запросов JPQL, Criteria API и жизненный цикл сущности. Кода в ней нет, только контракт.
Hibernate это реализация этой спецификации, самая распространённая. Помимо JPA у него есть собственные возможности: свои типы, фильтры, гибкие стратегии кэширования, @BatchSize, статистика.
Часто рядом стоит третий слой, Spring Data JPA: он генерирует реализации репозиториев по именам методов и работает поверх JPA, а не вместо неё.
Дальше объясните главное понятие, контекст персистентности. Это кэш первого уровня в границах транзакции. Загруженная сущность становится управляемой, и её изменения записываются в базу автоматически при сбросе, без явного вызова сохранения. Это называется грязной проверкой и удивляет тех, кто ждал явного save.
Состояния сущности: новая (не связана с контекстом), управляемая, отсоединённая (контекст закрыт), удалённая.
Что обязательно назвать из практики:
- ленивая загрузка: связи по умолчанию
LAZYдля коллекций иEAGERдля «к одному», и обращение к ленивой связи после закрытия контекста даётLazyInitializationException; - проблема N+1: список из ста сущностей плюс сто запросов за связями. Лечится соединением в запросе,
@EntityGraphили@BatchSize; - чем смотреть: включённый показ SQL и счётчик запросов, иначе ORM скрывает реальную нагрузку;
- пакетная вставка: без настройки размера пачки каждая сущность уходит отдельным запросом.
Где спотыкаются
Считают JPA и Hibernate синонимами.
Не знают про грязную проверку и вызывают сохранение вручную на управляемой сущности.
Ставят везде EAGER, чтобы убрать исключение ленивой загрузки, и получают тяжёлые запросы.
Никогда не смотрят на сгенерированный SQL.