JPA, Hibernate и JDBC: соответствие интерфейсов

Сравнение полезно как карта слоёв, но пары не являются полными аналогами.

ЗадачаJPAHibernate APIJDBC
фабрика ресурсовEntityManagerFactorySessionFactoryDataSource
единица работыEntityManagerSessionConnection
граница транзакцииEntityTransactionTransactionConnection.commit/rollback
объектный запросQuery, TypedQueryQuery—
SQL-запросnative querynative queryPreparedStatement
чтение результатасущности, DTO, scalarсущности, DTO, scalarResultSet

EntityManager обычно оборачивает Hibernate Session, а Session использует JDBC Connection. Получать внутренний объект можно через unwrap, но такой код сильнее связан с провайдером.

Главное отличие единицы работы

Connection знает о SQL и транзакции, но не следит за Java-объектами. EntityManager дополнительно содержит Persistence Context: одну сущность на сочетание типа и идентификатора, снимки для dirty checking и очередь изменений.

entityManager.unwrap(org.hibernate.Session.class)
             .doWork(connection -> {
                 // точечная операция JDBC в той же транзакции
             });

Прямой JDBC внутри ORM-транзакции требует учитывать порядок flush: данные в объектах могут ещё не попасть в таблицу.

Вопросы для повторения

  1. EntityManagerFactory создают на каждый запрос? Нет, это тяжёлый потокобезопасный объект приложения.
  2. EntityManager потокобезопасен? Нет, его область обычно совпадает с одной транзакцией или запросом.
  3. DataSource равен EntityManagerFactory? Нет: первый выдаёт соединения, второй создаёт контексты ORM и хранит метаданные.
  4. Зачем нужен unwrap? Для точечной возможности конкретного провайдера; это осознанный выход за стандарт JPA.

Связано: JPA Hibernate ORM, EntityManager, JDBC.