From 5dae52c07a289f2a5140135bcd9d35802972216e Mon Sep 17 00:00:00 2001 From: Konstantin Krivopustov Date: Fri, 1 Mar 2013 11:57:29 +0000 Subject: [PATCH] EntityManager and Query API changes (doc) #PL-1899 --- doc/content/manual/ru/chapter_framework.xml | 221 +++++++++++--------- 1 file changed, 122 insertions(+), 99 deletions(-) diff --git a/doc/content/manual/ru/chapter_framework.xml b/doc/content/manual/ru/chapter_framework.xml index 20c7dd246d..034411eadf 100644 --- a/doc/content/manual/ru/chapter_framework.xml +++ b/doc/content/manual/ru/chapter_framework.xml @@ -1611,7 +1611,9 @@ String formattedValue = format.format(value);
Интерфейсы инфраструктуры - Интерфейсы инфраструктуры обеспечивают доступ к часто используемой функциональности платформы. Большинство из этих интерфейсов расположены в модуле global и могут быть использованы как на среднем слое, так и в блоках клиентского уровня, но некоторые доступны только коду среднего слоя. + Интерфейсы инфраструктуры обеспечивают доступ к часто используемой функциональности платформы. Большинство из этих интерфейсов расположены в модуле global и могут быть использованы как на среднем слое, так и в блоках клиентского уровня, но некоторые (например + Persistence + ) доступны только коду среднего слоя. Интерфейсы инфраструктуры реализуются бинами Spring Framework, поэтому они могут быть инжектированы в любые другие управляемые компоненты (Managed Beans, сервисы среднего слоя, контроллеры экранов универсального пользовательского интерфейса. Кроме того, как и любые другие бины, интерфейсы инфраструктуры могут быть получены с помощью статических методов класса AppBeans, и использоваться в неуправляемых компонентах (POJO, вспомогательных классах и пр.).
@@ -1762,92 +1764,6 @@ tools.foo();((MyMessageTools) messages.getTools tools.foo();((MyMetadataTools) metadata.getTools()).foo();
-
- Persistence - Интерфейс уровня Middleware, являющийся точкой входа в функциональность хранения данных в БД. - Интерфейс Persistence доступен только в модуле core проекта приложения. - - Методы интерфейса: - - createTransaction(), getTransaction() - получить интерфейс управления транзакциями - - - isInTransaction() - определяет, существует ли в данный момент активная транзакция - - - getEntityManager() - возвращает экземпляр - EntityManager - для текущей транзакции - - - isSoftDeletion() - позволяет определить, активен ли режим мягкого удаления - - - setSoftDeletion() - устанавливает или отключает режим мягкого удаления. Влияет на аналогичный признак всех создаваемых экземпляров EntityManager. По умолчанию мягкое удаление включено. - - - getDbDialect() - возвращает диалект используемой в данный момент базы данных. Интерфейс DbDialect определяет тип БД и некоторые специфические для данной БД параметры. - В прикладном коде данный метод можно использовать для определения типа используемой БД, например:@Inject -protected Persistence persistence; -... -if (persistence.getDbDialect() instanceof PostgresDbDialect) -... - - - getDataSource() - получить javax.sql.DataSource для используемой в данный момент базы данных. - - Для всех объектов javax.sql.Connection, получаемых методом getDataSource().getConnection(), необходимо после использования соединения вызвать метод close() в секции finally. В противном случае соединение не вернется в пул, через какое-то время пул переполнится, и приложение не сможет выполнять запросы к базе данных. - - - - getTools() - возвращает экземпляр интерфейса PersistenceTools (см. ниже). - - -
- PersistenceTools - ManagedBean, содержащий вспомогательные методы работы с хранилищем данных. Интерфейс PersistenceTools можно получить либо методом Persistence.getTools(), либо как любой другой бин - инжекцией или через класс AppBeans. - Методы PersistenceTools: - - getDirtyFields() - возвращает коллекцию имен атрибутов сущности, измененных со времени последней загрузки экземпляра из БД. Для новых экземпляров возвращает пустую коллекцию. - - - isLoaded() - определяет, загружен ли из БД указанный атрибут экземпляра. Атрибут может быть не загружен, если он не указан в примененном при загрузке представлении. - Данный метод работает только для экземпляров в состоянии Managed. - - - getReferenceId() - возвращает идентификатор связанной сущности без загрузки ее из БД. - Предположим, в персистентный контекст загружен экземпляр Order, и нужно получить значение идентификатора экземпляра Customer, связанного с данным Заказом. Стандартное решение order.getCustomer().getId() приведет к выполнению SQL запроса к БД для загрузки экземпляра Customer, что в данном случае избыточно, так как значение идентификатора Покупателя физически находится также и в таблице Заказов. Выполнение же persistence.getTools().getReferenceId(order, "customer")не вызывет никаких дополнительных запросов к базе данных. - Данный метод работает только для экземпляров в состоянии Managed. - - - reloadEntity() - перезагрузить экземпляр сущности с указанным представлением. Данный метод должен вызываться внутри активной транзакции. - - - Для расширения набора вспомогательных методов в конкретном приложении бин PersistenceTools можно переопределить. Примеры работы с расширенным интерфейсом:MyPersistenceTools tools = persistence.getTools(); -tools.foo();((MyPersistenceTools) persistence.getTools()).foo(); -
-
- PersistenceHelper - Вспомогательный класс для получения информации о персистентных сущностях. В отличие от бинов Persistence и PersistenceTools доступен на всех уровнях приложения. - Методы PersistenceHelper: - - isNew() - определяет, является ли переданный экземпляр только что созданным, т.е. находящимся в состоянии New. Возвращает true также если экземпляр не является персистентной сущностью. - - - isDetached() - определяет, находится ли переданный экземпляр в состоянии Detached. Возвращает true также если экземпляр не является персистентной сущностью. - - - isSoftDeleted() - определяет, поддерживает ли переданный класс сущности мягкое удаление - - - getEntityName() - возвращает имя сущности, заданное в аннотации @Entity - - - getTableName() - возвращает имя таблицы БД, хранящей экземпляры сущности, заданное в аннотации @Table - - -
-
Resources Обеспечивает загрузку ресурсов по следующим правилам: @@ -2959,6 +2875,90 @@ public String foo(String value) { Например, вызов метода JMX-бина из встроенной в Web Client консоли JMX, если бин находится в той же JVM, что и блок WebClient, к которому в данный момент подключен пользователь, будет выполнен от имени текущего зарегистрированного в системе пользователя, независимо от наличия системной аутентификации.
+
+ Интерфейс Persistence + Интерфейс инфраструктуры, являющийся точкой входа в функциональность хранения данных в БД. + Методы интерфейса: + + createTransaction(), getTransaction() - получить интерфейс управления транзакциями + + + isInTransaction() - определяет, существует ли в данный момент активная транзакция + + + getEntityManager() - возвращает экземпляр + EntityManager + для текущей транзакции + + + isSoftDeletion() - позволяет определить, активен ли режим мягкого удаления + + + setSoftDeletion() - устанавливает или отключает режим мягкого удаления. Влияет на аналогичный признак всех создаваемых экземпляров EntityManager. По умолчанию мягкое удаление включено. + + + getDbDialect() - возвращает диалект используемой в данный момент базы данных. Интерфейс DbDialect определяет тип БД и некоторые специфические для данной БД параметры. + В прикладном коде данный метод можно использовать для определения типа используемой БД, например:@Inject +protected Persistence persistence; +... +if (persistence.getDbDialect() instanceof PostgresDbDialect) +... + + + getDataSource() - получить javax.sql.DataSource для используемой в данный момент базы данных. + + Для всех объектов javax.sql.Connection, получаемых методом getDataSource().getConnection(), необходимо после использования соединения вызвать метод close() в секции finally. В противном случае соединение не вернется в пул, через какое-то время пул переполнится, и приложение не сможет выполнять запросы к базе данных. + + + + getTools() - возвращает экземпляр интерфейса PersistenceTools (см. ниже). + + +
+ PersistenceTools + ManagedBean, содержащий вспомогательные методы работы с хранилищем данных. Интерфейс PersistenceTools можно получить либо методом Persistence.getTools(), либо как любой другой бин - инжекцией или через класс AppBeans. + Методы PersistenceTools: + + getDirtyFields() - возвращает коллекцию имен атрибутов сущности, измененных со времени последней загрузки экземпляра из БД. Для новых экземпляров возвращает пустую коллекцию. + + + isLoaded() - определяет, загружен ли из БД указанный атрибут экземпляра. Атрибут может быть не загружен, если он не указан в примененном при загрузке представлении. + Данный метод работает только для экземпляров в состоянии Managed. + + + getReferenceId() - возвращает идентификатор связанной сущности без загрузки ее из БД. + Предположим, в персистентный контекст загружен экземпляр Order, и нужно получить значение идентификатора экземпляра Customer, связанного с данным Заказом. Стандартное решение order.getCustomer().getId() приведет к выполнению SQL запроса к БД для загрузки экземпляра Customer, что в данном случае избыточно, так как значение идентификатора Покупателя физически находится также и в таблице Заказов. Выполнение же persistence.getTools().getReferenceId(order, "customer")не вызывет никаких дополнительных запросов к базе данных. + Данный метод работает только для экземпляров в состоянии Managed. + + + reloadEntity() - перезагрузить экземпляр сущности с указанным представлением. Данный метод должен вызываться внутри активной транзакции. + + + Для расширения набора вспомогательных методов в конкретном приложении бин PersistenceTools можно переопределить. Примеры работы с расширенным интерфейсом:MyPersistenceTools tools = persistence.getTools(); +tools.foo();((MyPersistenceTools) persistence.getTools()).foo(); +
+
+ PersistenceHelper + Вспомогательный класс для получения информации о персистентных сущностях. В отличие от бинов Persistence и PersistenceTools доступен на всех уровнях приложения. + Методы PersistenceHelper: + + isNew() - определяет, является ли переданный экземпляр только что созданным, т.е. находящимся в состоянии New. Возвращает true также если экземпляр не является персистентной сущностью. + + + isDetached() - определяет, находится ли переданный экземпляр в состоянии Detached. Возвращает true также если экземпляр не является персистентной сущностью. + + + isSoftDeleted() - определяет, поддерживает ли переданный класс сущности мягкое удаление + + + getEntityName() - возвращает имя сущности, заданное в аннотации @Entity + + + getTableName() - возвращает имя таблицы БД, хранящей экземпляры сущности, заданное в аннотации @Table + + +
+
Слой ORM
@@ -3015,10 +3015,32 @@ public String foo(String value) { Экземпляр EntityManager содержит в себе "персистентный контекст" – набор экземпляров сущностей, загруженных из БД или только что созданных. Персистентный контекст является своего рода кэшем данных в рамках транзакции. EntityManager автоматически сбрасывает в БД все изменения, сделанные в его персистентном контексте, в момент коммита транзакции, либо при явном вызове метода flush(). - Интерфейс EntityManager, используемый в CUBA-приложениях, в основном повторяет стандартный javax.persistence.EntityManager. Рассмотрим специфичные методы: + Интерфейс EntityManager, используемый в CUBA-приложениях, в основном повторяет стандартный javax.persistence.EntityManager. Рассмотрим его основные методы: - setView() - устанавливает представление, с которым будет производиться последующая загрузка сущностей методом find() либо JPQL запросами. В результате энергично загружены будут все не-lazy атрибуты представления. + persist() - вводит новый экземпляр сущности в персистентный контекст. При коммите транзакции командой SQL INSERT в БД будет создана соответствующая запись. + + + merge() - переносит состояние отсоединенного экземпляра сущности в персистентный контекст следующим образом: из БД загружается экземпляр с тем же идентификатором, в него переносится состояние переданного Detached экземпляра и возвращается загруженный Managed экземпляр. Далее надо работать именно с возвращенным Managed экземпляром. При коммите транзакции командой SQL UPDATE в БД будет сохранено состояние данного экземпляра. + + + remove() - удалить объект из базы данных, либо, если включен режим мягкого удаления, установить атрибуты deleteTs и deletedBy. + Если переданный экземпляр находится в Detached состоянии, сначала выполняется merge(). + + + find() - загружает экземпляр сущности по идентификатору. + При формировании запроса к БД учитывается представление, переданное в параметре данного метода, либо установленное для всего EntityManager методом setView(). В результате в персистентном контексте окажется граф объектов, для которого загружены все не-lazy атрибуты представления. Остальные атрибуты можно дозагрузить обращением к соответствующим методам доступа объектов, либо вызовом метода fetch(). + + + createQuery() - создать объект Query для выполнения JPQL запроса. + Рекомендуется использовать вариант метода с передачей класса сущности для получения экземпляра TypedQuery. + + + createNativeQuery() - создать объект Query для выполнения SQL запроса. + + + setView() - устанавливает представление по умолчанию, с которым будет производиться последующая загрузка сущностей методом find() либо JPQL запросами. В результате энергично загружены будут все не-lazy атрибуты представления. Если в данный метод передать null, либо не вызывать его вообще, загрузка будет производиться в соответствие с правилами аннотаций сущностей. + Представления, явно переданные в метод find() или установленные в объекте Query имеют приоритет над установленным данным методом. addView() - аналогичен методу setView(), но в случае наличия уже установленного в EntityManager представления, не заменяет его, а добавляет атрибуты переданного представления. @@ -3027,6 +3049,9 @@ public String foo(String value) { fetch() - обеспечивает для экземпляра сущности загрузку всех атрибутов указанного представления, включая lazy атрибуты. Экземпляр сущности должен быть в Managed состоянии. Данный метод рекомендуется вызывать перед коммитом транзакции, если представление содержит lazy атрибуты, а экземпляр сущности нужно отправить на клиентский уровень. В этом случае только после вызова fetch() можно быть уверенным, что все нужные клиентсткому коду атрибуты действительно загружены. + + reload() - перезагрузить экземпляр сущности с указанным представлением. Обеспечивает загрузку всех атрибутов представления, вызывая внутри себя метод fetch(). + isSoftDeletion() - проверяет, находится ли данный EntityManager в режиме мягкого удаления. @@ -3064,7 +3089,6 @@ public String foo(String value) { Экземпляр, загруженный из БД и отсоединенный от своего персистентного контекста (вследствие закрытия транзакции или сериализации). Изменения, вносимые в Detached экземпляр, запоминаются в самом этом экземпляре (в полях, добавленных с помощью bytecode enhancement). Эти изменения будут сохранены в БД, только если данный экземпляр будет снова переведен в состояние Managed путем передачи в метод EntityManager.merge(). - Метод merge() выполняет следующее: загружает из БД экземпляр с тем же идентификатором, переносит в него состояние переданного Detached экземпляра и возвращает загруженный Managed экземпляр. Далее надо работать именно с возвращенным Managed экземпляром. @@ -10623,15 +10647,14 @@ public class ExtUser extends User { . Создаем класс с нужным методом:public class ExtPersistenceTools extends PersistenceTools { - public Entity reloadStartingTransaction(Entity entity, String... viewNames) { - Transaction tx = persistence.createTransaction(); - try { - Entity reloadedEntity = reloadEntity(entity, viewNames); - tx.commit(); - return reloadedEntity; - } finally { - tx.end(); - } + public Entity reloadInSeparateTransaction(final Entity entity, final String... viewNames) { + Entity result = persistence.createTransaction().execute(new Transaction.Callable<Entity>() { + @Override + public Entity call(EntityManager em) { + return em.reload(entity, viewNames); + } + }); + return result; } } Регистрируем класс в spring.xml модуля core проекта с тем же идентификатором, что и бин платформы:<bean id="cuba_PersistenceTools" class="com.sample.sales.core.ExtPersistenceTools"/>