Зачем нужен интерфейс JPA поверх ORM?
Что проверяют
Понимаете ли вы разницу между спецификацией и реализацией: JPA это набор интерфейсов и правил, а Hibernate или EclipseLink это ORM, которая их выполняет. Следом обычно спрашивают, где кончается JPA и начинается Spring Data JPA и меняли ли вы когда-нибудь провайдера.
Как отвечать
- что такое JPA: спецификация, сейчас она называется Jakarta Persistence, с Jakarta EE 9 пакет
jakarta.persistenceвместоjavax.persistence. Сама ничего не делает, работает только вместе с провайдером; - что она стандартизирует: аннотации маппинга (
@Entity,@Id,@OneToMany),EntityManager, контекст персистентности с отслеживанием изменений, жизненный цикл сущности (new, managed, detached, removed), JPQL и Criteria API, колбэки вроде@PrePersist; - зачем она поверх ORM: код и знания не привязаны к одной библиотеке, а фреймворки интегрируются со стандартным API. Spring, Quarkus и серверы Jakarta EE работают с
EntityManager, а не с внутренностями Hibernate; - слои в Spring: Spring Data JPA генерирует репозитории поверх JPA, JPA работает через провайдера, провайдер ходит в базу через JDBC.
Честная оговорка усилит ответ: сменить провайдера в живом проекте удаётся редко. Код обрастает возможностями Hibernate, которых нет в стандарте (@BatchSize, @Formula, unwrap(Session.class)), и это нормальная цена. Реальная польза стандарта в едином API и в том, что разработчик переходит между проектами без переобучения.
Где спотыкаются
Ставят знак равенства между JPA и Hibernate, а Spring Data JPA называют «ещё одной ORM».
Приписывают JPA управление транзакциями. В спецификации есть EntityTransaction и интеграция с JTA, а привычный @Transactional в Spring-проекте обслуживает JpaTransactionManager, это уже Spring.
Называют независимость от СУБД заслугой JPA. Её дают диалекты провайдера и JPQL, а первый же запрос через createNativeQuery эту независимость отменяет.