5.4.4.1. EntityManager
EntityManager
- основной интерфейс ORM, служит для управления персистентными сущностями.
Tip
|
В разделе 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
.TipВ отличие от 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). Однако, если загружаемая сущность кэшируется, то данный признак игнорируется, и сущность все равно будет загружена со всеми локальными атрибутами.