3.4.4.1. EntityManager
EntityManager - основной интерфейс ORM, служит для управления персистентными сущностями.
|
В разделе DataManager vs. EntityManager приведена информация о различиях между EntityManager и DataManager. |
Ссылку на EntityManager можно получить через интерфейс Persistence, вызовом метода getEntityManager(). Полученный экземпляр EntityManager привязан к текущей транзакции, то есть все вызовы getEntityManager() в рамках одной транзакции возвращают один и тот же экземпляр EntityManager. После завершения транзакции обращения к данному экземпляру невозможны.
Экземпляр EntityManager содержит в себе персистентный контекст – набор экземпляров сущностей, загруженных из БД или только что созданных. Персистентный контекст является своего рода кэшем данных в рамках транзакции.EntityManager автоматически сбрасывает в БД все изменения, сделанные в его персистентном контексте, в момент коммита транзакции, либо при явном вызове метода flush().
Интерфейс EntityManager, используемый в CUBA-приложениях, в основном повторяет стандартный javax.persistence.EntityManager. Рассмотрим его основные методы:
-
persist()- вводит новый экземпляр сущности в персистентный контекст. При коммите транзакции командой SQLINSERTв БД будет создана соответствующая запись. -
merge()- переносит состояние отсоединенного экземпляра сущности в персистентный контекст следующим образом: из БД загружается экземпляр с тем же идентификатором, в него переносится состояние переданного Detached экземпляра и возвращается загруженный Managed экземпляр. Далее надо работать именно с возвращенным Managed экземпляром. При коммите транзакции командой SQLUPDATEв БД будет сохранено состояние данного экземпляра. -
remove()- удалить объект из базы данных, либо, если включен режим мягкого удаления, установить атрибутыdeleteTsиdeletedBy.Если переданный экземпляр находится в Detached состоянии, сначала выполняется
merge(). -
find()- загружает экземпляр сущности по идентификатору.При формировании запроса к БД учитывается представление, переданное в параметре данного метода. В результате в персистентном контексте окажется граф объектов, для которого загружены все атрибуты представления. Если не передано никакого представления, по умолчанию будет использовано представление
_local.В отличие от DataManager, все локальные атрибуты сущностей загружаются независимо от того, указаны ли они в представлении или нет. В
EntityManagerпредставление влияет только на загрузку атрибутов-ссылок. -
createQuery()- создать объектQueryилиTypedQueryдля выполнения JPQL запроса. -
createNativeQuery()- создать объектQueryдля выполнения SQL запроса. -
addView()- аналогичен методуsetView(), но в случае наличия уже установленного вEntityManagerпредставления, не заменяет его, а добавляет атрибуты переданного представления. -
reload()- перезагрузить экземпляр сущности с указанным представлением. -
isSoftDeletion()- проверяет, находится ли данныйEntityManagerв режиме мягкого удаления. -
setSoftDeletion()- устанавливает режим мягкого удаления для данного экземпляраEntityManager. -
getConnection()- возвращаетjava.sql.Connection, через который выполняет запросы данный экземплярEntityManager, и, соответственно, текущая транзакция. Закрывать такое соединение не нужно, оно будет закрыто при завершении транзакции. -
getDelegate()- возвращаетjavax.persistence.EntityManager, предоставляемый реализацией ORM.
Пример использования EntityManager в сервисе:
@Service(SalesService.NAME)
public class SalesServiceBean implements SalesService {
@Inject
private Persistence persistence;
@Override
public BigDecimal calculateSales(UUID customerId) {
BigDecimal result;
// start transaction
try (Transaction tx = persistence.createTransaction()) {
// get EntityManager for the current transaction
EntityManager em = persistence.getEntityManager();
// create and execute Query
Query query = em.createQuery(
"select sum(o.amount) from sample_Order o where o.customer.id = :customerId");
query.setParameter("customerId", customerId);
result = (BigDecimal) query.getFirstResult();
// commit transaction
tx.commit();
}
return result != null ? result : BigDecimal.ZERO;
}
}
- Частичные сущности
-
По умолчанию, представления в EntityManager влияют только на загрузку связей, т.е. все локальные атрибуты всегда загружаются.
Вы можете заставить EntityManager загружать частичные сущности, если установите свойство loadPartialEntities представления в true (например, так делает DataManager). Однако, если загружаемая сущность кэшируется, то данный признак игнорируется, и сущность все равно будет загружена со всеми локальными атрибутами.