4.2.6.10. DataManager
Интерфейс DataManager является универсальным средством для загрузки графов сущностей из базы данных, и для сохранения изменений, произведенных в detached экземплярах сущностей.
DataManager всегда стартует новую транзакцию и по завершении работы выполняет коммит, таким образом возвращая сущности в detached состоянии.
DataManager всегда проверяет ограничения подсистемы безопасности на операции и атрибуты сущностей, когда вызывается с клиентской стороны, и игнорирует их по умолчанию когда вызывается из кода Middleware. Если вы хотите, чтобы DataManager проверял эти права доступа и при вызове на среднем слое, получите методом DataManager.secure() специальный объект-обертку и вызывайте методы у него. В качестве альтернативы, вы можете установить свойство приложения cuba.dataManagerChecksSecurityOnMiddleware, чтобы проверка прав работала для всего приложения. Заметьте, что ограничения групп доступа (row-level security) применяются всегда, независимо от того, был ли вызов с клиентского или со среднего слоя.
Методы DataManager:
-
load(),loadList()- загружает граф сущностей в соответствии с параметрами переданного объектаLoadContext.В
LoadContextобязательно должен быть передан либо JPQL-запрос, либо идентификатор сущности. Если передано и то и другое, используется запрос, а идентификатор игнорируется.Правила создания запросов аналогичны описанным в Выполнение JPQL-запросов. Отличием является то, что в запросе
LoadContextмогут быть использованы только именованные параметры, позиционные не поддерживаются.Методы
load()иloadList()проверяют наличие у пользователя праваEntityOp.READна загружаемую сущность. Кроме того, при извлечении сущностей из БД накладываются ограничения групп доступа.Примеры загрузки сущностей в контроллере экрана:
@Inject private DataManager dataManager; private Book loadBookById(UUID bookId) { LoadContext loadContext = LoadContext.create(Book.class) .setId(bookId).setView("book.edit"); return dataManager.load(loadContext); } private List<BookPublication> loadBookPublications(UUID bookId) { LoadContext loadContext = LoadContext.create(BookPublication.class) .setQuery(LoadContext.createQuery("select p from library$BookPublication p where p.book.id = :bookId") .setParameter("bookId", bookId)) .setView("bookPublication.full"); return dataManager.loadList(loadContext); } -
loadValues()- загружает список пар ключ-значение. Метод принимаетValueLoadContext, в котором задается запрос и список ключей. Возвращаемый список содержит экземплярыKeyValueEntity. Например:ValueLoadContext context = ValueLoadContext.create() .setQuery(ValueLoadContext.createQuery( "select o.customer, sum(o.amount) from demo$Order o " + "where o.date >= :date group by o.customer") .setParameter("date", orderDate)) .addProperty("customer") .addProperty("sum"); List<KeyValueEntity> list = dataManager.loadValues(context); -
getCount()- возвращает количество записей для запроса, переданного в метод. Когда возможно, для максимальной производительности, стандартная реализация в классеRdbmsStoreвыполняет запросselect count()с условиями исходного запроса. -
commit()- сохраняет в базе данных набор сущностей, переданный в объектеCommitContext. Отдельно указываются коллекции сущностей, которые нужно сохранить, и которые нужно удалить.Метод возвращает набор экземпляров сущностей, возвращенных из метода EntityManager.merge(), то есть по сути свежие экземпляры, только что обновленные в БД. Дальнейшая работа должна производиться именно с этими возвращенными экземплярами, чтобы предотвратить потерю данных или исключения оптимистичной блокировки. Для того, чтобы обеспечить наличие нужных атрибутов у возвращенных сущностей, с помощью мэп
CommitContext.getViews()можно указать представление для каждого сохраняемого экземпляра.Метод
commit()проверяет наличие у пользователя праваEntityOp.UPDATEна изменяемые сущности, иEntityOp.DELETEна удаляемые.Примеры сохранения коллекций сущностей:
@Inject private DataManager dataManager; private void saveBookInstances(List<BookInstance> toSave, List<BookInstance> toDelete) { CommitContext commitContext = new CommitContext(toSave, toDelete); dataManager.commit(commitContext); } private Set<Entity> saveAndReturnBookInstances(List<BookInstance> toSave, View view) { CommitContext commitContext = new CommitContext(); for (BookInstance bookInstance : toSave) { commitContext.addInstanceToCommit(bookInstance, view); } return dataManager.commit(commitContext); } -
reload()- удобный метод для перезагрузки экземпляра сущности с требуемым представлением. Делегирует выполнение методуload(). -
remove()- удаляет экземпляр сущности из базы данных. Делегирует выполнение методуcommit().
В процессе загрузки данных DataManager может реализовывать дополнительную функциональность, описанную ниже.
|
Tip
|
В разделе DataManager vs. EntityManager приведена информация о различиях между DataManager и EntityManager. |