Простое объяснение Persistence Context в Java и JPA
Пройдите тест, узнайте какой профессии подходите
Быстрый ответ
Контекст сохранности (Persistence Context) — совокупность объектов сущностей под управлением контекста, обеспечивающая синхронизацию состояния объектов с базой данных. Управляемый EntityManager, контекст сохранности действует как кэш, сокращая число запросов к базе данных и отслеживая изменения в рамках транзакции. Все изменения сохраняются в базе данных при завершении транзакции:
// Настройка 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
остается актуализирован.
EntityManager и его Фабрика
EntityManager — интерфейс, являющийся связующим звеном с контекстом сохранности. Он управляет жизненным циклом объектов сущностей, включая создание, удаление объектов, поиск по идентификатору и выполнение запросов.
EntityManagerFactory — класс, предназначенный для генерации экземпляров EntityManager. Обычно инициализируется единожды при запуске приложения:
// Инициализация EntityManagerFactory
EntityManagerFactory emf = Persistence.createEntityManagerFactory("my-persistence-unit");
EntityManager em = emf.createEntityManager(); // Создание экземпляра EntityManager
Жизненный цикл сущности: от рождения до смерти
Каждая сущность в контексте сохранности проходит цикл жизни, включающий следующие этапы:
- Новая: Сущность только что создана, еще не связана с базой данных.
- Управляемая: Сущность находится под управлением контекста сохранности.
- Отсоединенная: Сущность была отсоединена от контекста сохранности.
- Удаленная: Сущность отмечена для удаления из базы данных при следующем commit.
Кэш первого уровня: ваше секретное оружие
Встроенный кэш первого уровня контекста сохранности дает возможность уменьшить количество запросов к базе данных, используя уже загруженные сущности:
// Применение кэша первого уровня для пресечения избыточных запросов к БД
Customer customer = em.find(Customer.class, customerID);
Визуализация
Если представить контекст сохранности как альбом для коллекции наклеек:
📖 Контекст Сохранности: Альбом для коллекции сущностей в виде наклеек (🏷️)
| Действие | Поведение в альбоме |
| ----------------------- | ----------------- |
| persist(entity) | Добавляем новую наклейку 🏷️ |
| find(Class, id) | Ищем наклейку 🔍 |
| merge(entity) | Обновляем наклейку новой версией 🔄 |
| remove(entity) | Удаляем наклейку 🗑️ |
| flush() | Фиксируем изменения в альбоме ✅ |
Все операции с сущностями (наклейками) выполняются сначала в альбоме.
Сброс: незаметный герой
Сброс (Flush) — операция, обеспечивающая синхронизацию состояния объектов в контексте сохранности с базой данных. Изменения в транзакции моментально не отражаются в базе данных, а сохраняются при завершении транзакции:
// Обновление сущности в транзакции
em.getTransaction().begin();
Book book = em.find(Book.class, 1);
book.setTitle("Программирование на Java");
// Сброс изменений в базу данных
em.getTransaction().commit();
Управление консистентностью: руководитель хаоса
Контекст сохранности помогает управлять параллелизмом, используя механизм оптимистической блокировки для минимизации конфликтов при обновлении данных.
Подключение сущности: отсоединяйся, отдыхай и объединяй
Отсоединенная сущность может быть повторно интегрирована в контекст сохранности и синхронизирована с базой данных:
// Подключение отсоединенной сущности к контексту сохранности
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)
Полезные материалы
- Java Platform, Enterprise Edition: The Java EE Tutorial (Release 7) – Официальное руководство от Oracle.
- Java persistence API – Tutorial – Руководство по использованию EntityManager JPA.
- Java Persistence/Entity – Wikibooks – Основы Java Persistence из открытых источников.
- Jakarta Persistence – Wikipedia – Общая информация о Java Persistence API из Wikipedia.
- Persistence Layers with Spring Data JPA – Обзор использования Spring Data JPA от Baeldung.