Этап 1 - Введение в JPA: база данных, ORM, JPA и Hibernate
База данных - это система, которая хранит данные приложения структурированно и надежно. Backend-приложение может держать объекты в памяти только пока работает процесс, но реальному продукту нужны данные после перезапуска, для многих пользователей и с правилами, которые защищают целостность. Реляционные базы данных, например PostgreSQL, хранят данные в таблицах. Таблица содержит строки, строка представляет одну запись, а колонки описывают поля этой записи.
Java-приложение может обращаться к реляционной базе через JDBC. JDBC - это низкоуровневый Java API для открытия соединений, отправки SQL, передачи параметров и чтения результатов. Он мощный, но многословный. Если в каждом service method писать SQL вручную, разработчику приходится собирать insert, select, update, delete, преобразовывать каждую строку в Java-объект, следить за соединениями и синхронизировать имена колонок с именами полей.

Почему ручной JDBC становится неудобным
Ручной SQL сам по себе не является проблемой. SQL остается языком базы данных, и backend-разработчик должен его понимать. Проблема появляется, когда один и тот же mapping-код повторяется везде. В таблице users могут быть колонки id, email, name, created_at, а в Java есть класс User с полями id, email, name, createdAt. При raw JDBC каждый запрос должен вручную копировать значения в обе стороны.
Из этого появляются риски. Переименование колонки ломает код во многих местах. Новое поле нужно добавить во все insert-запросы и мапперы. Обычная операция чтения требует boilerplate-кода еще до того, как началась бизнес-логика. Чем больше приложение, тем сильнее низкоуровневый доступ к данным скрывает реальный сценарий.
Что означает ORM
ORM означает Object-Relational Mapping: отображение между Java-объектами и таблицами реляционной базы. В Java разработчик работает с объектами, полями, ссылками и классами. В реляционной базе он работает с таблицами, строками, колонками, primary keys и foreign keys. ORM описывает, как эти два мира соответствуют друг другу.
Например, класс User можно связать с таблицей users. Один объект User представляет одну строку. Поле email соответствует колонке email. Связь от Order к User соответствует foreign key, например user_id. ORM provider использует это описание, чтобы генерировать SQL и превращать строки обратно в объекты.
У ORM есть понятные преимущества: меньше boilerplate, более естественная объектная модель, автоматическое отслеживание изменений, repository abstraction и удобная интеграция с транзакциями. Но есть и недостатки. Сгенерированный SQL может быть неэффективным, если mapping или запрос составлены плохо. Lazy loading может удивлять новичков. Сложные отчеты и массовые операции иногда лучше писать напрямую на SQL. ORM - это инструмент, а не замена знаниям о базе данных.
JPA, Hibernate и слои приложения
JPA - это спецификация, а не библиотека, которая напрямую общается с базой. Это стандартный набор аннотаций и интерфейсов для persistence в Java. Спецификация описывает правила, но сама не выполняет работу с базой. JPA определяет такие понятия, как @Entity, EntityManager, Persistence Context, состояния entity и JPQL.
Hibernate - это реализация JPA. Он читает JPA-аннотации, строит metadata о mapping, отслеживает managed entities, генерирует SQL, отправляет SQL через JDBC и преобразует строки базы в Java-объекты. Во многих Spring Boot приложениях разработчики говорят "JPA", хотя фактическим provider во время выполнения является Hibernate.
| Если ты пишешь такой код | Кто выполняет работу | Что реально происходит |
|---|---|---|
repository.save(user) | Spring Data JPA делегирует в JPA | Service вызывает repository method вместо ручной сборки insert. |
Mapping использует @Entity и @Column | JPA задает правила | Аннотации описывают, как Java-класс соответствует таблице и колонкам. |
| Приложению нужен настоящий SQL | Hibernate применяет mapping | Hibernate читает JPA metadata и генерирует SQL под конкретную базу. |
| SQL должен попасть в PostgreSQL | JDBC передает запрос | Hibernate все равно использует JDBC внутри, чтобы отправить SQL и получить rows. |
| Строка должна стать Java-объектом | Hibernate собирает entity | Значения из result set копируются в поля entity и отслеживаются в Persistence Context. |
В типичной Spring Boot архитектуре controller принимает HTTP-запрос, service координирует бизнес-операцию, repository загружает или сохраняет entities, Hibernate выполняет SQL, а база хранит строки. Такое разделение важно: controller не должен содержать детали базы, а repository не должен содержать бизнес-правила.
Как JPA работает во время выполнения
EntityManager - главный JPA-интерфейс для работы с entities. Он умеет сохранять новый объект, искать объект по id, удалять объект и создавать запросы. Spring Data JPA часто скрывает прямое использование EntityManager за repositories, но концепция важна, потому что repositories внутри делегируют работу JPA.
Persistence Context - это рабочая область, где JPA хранит managed entities. Если entity является managed, Hibernate знает этот объект и может отслеживать изменения. Когда транзакция коммитится, Hibernate сравнивает текущие значения полей с загруженным состоянием и генерирует SQL updates при необходимости. Поэтому service method может загрузить entity, изменить поле и положиться на commit транзакции.
У entity есть несколько базовых состояний. Новый объект, созданный через new, является transient. После сохранения или загрузки внутри persistence context он становится managed. После закрытия context он становится detached. Removed entity запланирована на удаление. Понимание этих состояний объясняет, почему одни изменения объекта попадают в базу, а другие нет.
Практика
Для практики создай Spring Boot проект с Spring Web, Spring Data JPA, PostgreSQL Driver и Validation. Запусти PostgreSQL локально или через Docker. Настрой spring.datasource.url, spring.datasource.username и spring.datasource.password. На время обучения включи SQL logging через spring.jpa.show-sql=true. Затем создай минимальную entity и repository и запусти приложение. Если подключение работает, Hibernate инициализирует JPA infrastructure, и проект будет готов к mapping сущностей.
Чек-лист понимания
- Могу объяснить, зачем база данных нужна помимо Java-памяти.
- Понимаю, что делает JDBC и почему raw JDBC становится повторяющимся.
- Могу определить ORM и назвать преимущества и риски.
- Знаю, что JPA - спецификация, а Hibernate - реализация.
- Могу описать поток controller-service-repository-database.