Простое объяснение Persistence Context в Java и JPA

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Контекст сохранности (Persistence Context) — совокупность объектов сущностей под управлением контекста, обеспечивающая синхронизацию состояния объектов с базой данных. Управляемый EntityManager, контекст сохранности действует как кэш, сокращая число запросов к базе данных и отслеживая изменения в рамках транзакции. Все изменения сохраняются в базе данных при завершении транзакции:

Java
Скопировать код
// Настройка EntityManager должна быть валидной
EntityManager em = entityManagerFactory.createEntityManager();
EntityTransaction transaction = em.getTransaction();

// Начало транзакции
transaction.begin();
// Загрузка объекта из базы данных с последующим кешированием в контексте сохранности
Book book = em.find(Book.class, id);
// Обработка операций с объектом
transaction.commit(); // Сохранение изменений в базе данных
em.close(); // Закрытие EntityManager обязательно

В данном случае em.find() проверяет контекст сохранности перед выполнением запроса к базе данных, transaction.commit() инициирует сохранение изменений, что приводит к обновлению данных в базе, а book остается актуализирован.

Кинга Идем в IT: пошаговый план для смены профессии

EntityManager и его Фабрика

EntityManager — интерфейс, являющийся связующим звеном с контекстом сохранности. Он управляет жизненным циклом объектов сущностей, включая создание, удаление объектов, поиск по идентификатору и выполнение запросов.

EntityManagerFactory — класс, предназначенный для генерации экземпляров EntityManager. Обычно инициализируется единожды при запуске приложения:

Java
Скопировать код
// Инициализация EntityManagerFactory
EntityManagerFactory emf = Persistence.createEntityManagerFactory("my-persistence-unit");
EntityManager em = emf.createEntityManager(); // Создание экземпляра EntityManager

Жизненный цикл сущности: от рождения до смерти

Каждая сущность в контексте сохранности проходит цикл жизни, включающий следующие этапы:

  • Новая: Сущность только что создана, еще не связана с базой данных.
  • Управляемая: Сущность находится под управлением контекста сохранности.
  • Отсоединенная: Сущность была отсоединена от контекста сохранности.
  • Удаленная: Сущность отмечена для удаления из базы данных при следующем commit.

Кэш первого уровня: ваше секретное оружие

Встроенный кэш первого уровня контекста сохранности дает возможность уменьшить количество запросов к базе данных, используя уже загруженные сущности:

Java
Скопировать код
// Применение кэша первого уровня для пресечения избыточных запросов к БД
Customer customer = em.find(Customer.class, customerID);

Визуализация

Если представить контекст сохранности как альбом для коллекции наклеек:

Markdown
Скопировать код
📖 Контекст Сохранности: Альбом для коллекции сущностей в виде наклеек (🏷️)
Markdown
Скопировать код
| Действие                | Поведение в альбоме  |
| ----------------------- | ----------------- |
| persist(entity)         | Добавляем новую наклейку 🏷️     |
| find(Class, id)         | Ищем наклейку 🔍 |
| merge(entity)           | Обновляем наклейку новой версией 🔄 |
| remove(entity)          | Удаляем наклейку 🗑️ |
| flush()                 | Фиксируем изменения в альбоме ✅ |

Все операции с сущностями (наклейками) выполняются сначала в альбоме.

Сброс: незаметный герой

Сброс (Flush) — операция, обеспечивающая синхронизацию состояния объектов в контексте сохранности с базой данных. Изменения в транзакции моментально не отражаются в базе данных, а сохраняются при завершении транзакции:

Java
Скопировать код
// Обновление сущности в транзакции
em.getTransaction().begin();
Book book = em.find(Book.class, 1);
book.setTitle("Программирование на Java");
// Сброс изменений в базу данных
em.getTransaction().commit();

Управление консистентностью: руководитель хаоса

Контекст сохранности помогает управлять параллелизмом, используя механизм оптимистической блокировки для минимизации конфликтов при обновлении данных.

Подключение сущности: отсоединяйся, отдыхай и объединяй

Отсоединенная сущность может быть повторно интегрирована в контекст сохранности и синхронизирована с базой данных:

Java
Скопировать код
// Подключение отсоединенной сущности к контексту сохранности
EntityManager newEm = entityManagerFactory.createEntityManager();
newEm.getTransaction().begin();
Book detachedBook = newEm.merge(book); // Объединение сущности
newEm.getTransaction().commit();

CRUD операции: замыкание круга

Контекст сохранности поддерживает операции CRUD:

  • Создание: persist(entity)
  • Чтение: find(entityClass, primaryKey) или createQuery()
  • Обновление: Прямое взаимодействие с управляемыми объектами.
  • Удаление: remove(entity)

Полезные материалы

  1. Java Platform, Enterprise Edition: The Java EE Tutorial (Release 7) – Официальное руководство от Oracle.
  2. Java persistence API – Tutorial – Руководство по использованию EntityManager JPA.
  3. Java Persistence/Entity – Wikibooks – Основы Java Persistence из открытых источников.
  4. Jakarta Persistence – Wikipedia – Общая информация о Java Persistence API из Wikipedia.
  5. Persistence Layers with Spring Data JPA – Обзор использования Spring Data JPA от Baeldung.
Свежие материалы