EntityManager
EntityManager — основной интерфейс JPA для работы с Persistence Context. Он не просто отправляет запросы, а управляет состоянием сущностей в рамках единицы работы.
Основные операции
| Метод | Смысл |
|---|---|
persist(entity) | сделать новый объект managed; метод ничего не возвращает |
find(Type.class, id) | найти по ключу; обычно сразу обращается к контексту или БД |
getReference(Type.class, id) | получить ссылку-прокси без гарантии немедленного SQL |
merge(entity) | скопировать состояние detached-объекта в managed-экземпляр и вернуть его |
remove(entity) | пометить managed-сущность на удаление |
flush() | синхронизировать изменения с БД |
clear() | отсоединить все сущности |
detach(entity) | отсоединить одну сущность |
refresh(entity) | перечитать состояние из БД |
Критическая деталь merge: переданный объект не становится managed.
Order managed = entityManager.merge(detached);
// дальше меняем managed, а не detachedЖизненный цикл и граница
В Spring EntityManager обычно предоставляется прокси, который направляет вызовы в контекст текущей транзакции. Хранить его в статическом поле или передавать между потоками нельзя.
После завершения контекста сущности становятся detached. Обращение к незагруженной ленивой связи тогда приводит к LazyInitializationException.
Запросы и flush
JPA может выполнить автоматический flush перед JPQL-запросом, чтобы запрос увидел изменения контекста. Режим COMMIT уменьшает такие синхронизации, но не отменяет flush перед фиксацией.
Вопросы для повторения
- Чем
findотличается отgetReference?findвозвращает данные либоnull;getReferenceможет вернуть прокси и сообщить об отсутствии строки позже. - Что возвращает
merge? Managed-копию; исходный объект остаётся detached. persistнемедленно делаетINSERT? Не всегда; SQL часто откладывается до flush, хотя стратегия ключа может потребовать ранней вставки.- Можно ли использовать один
EntityManagerв двух потоках? Нет. - Что очищает
clear? Весь persistence context; несинхронизированные изменения могут быть потеряны.
Связано: Жизненный цикл Entity в Hibernate, Transactional, LockModeType.