Журнал сущностей
Журнал сущностей - это механизм для отслеживания изменений, вносимых в JPA-сущности. Он фиксирует изменения атрибутов сущностей и предоставляет пользовательский интерфейс для запроса и отображения деталей изменений:
-
Какая сущность была изменена.
-
Старые и новые значения измененных атрибутов.
-
Когда сущность была изменена.
-
Какой пользователь изменил сущность.
Регистрация изменений
Журнал сущностей автоматически фиксирует изменения, вносимые в JPA-сущности при коммите транзакции при работе с DataManager или EntityManager. Он не функционирует при использовании нативного SQL.
Также, если вы загружаете сущности через EntityManager
, вы можете использовать бин EntityLog
напрямую для регистрации изменений в сущностях из кода вашего приложения. В этом случае вызывайте методы registerCreate()
, registerModify()
и registerDelete()
с параметром auto
, установленным в false
. Когда журнал сущностей вызывается фреймворком автоматически, этот параметр устанавливается в true
.
EntityLog может регистрировать изменения только для managed (управляемых) сущностей внутри транзакции. Это означает, что вы должны вызывать EntityLog из кода приложения только если вы используете EntityManager для загрузки данных. Сущности, загруженные с помощью DataManager , всегда являются detached (открепленными), и их изменения не могут быть зарегистрированы путем вызова EntityLog вручную.
|
Настройка журнала сущностей
Для использования административного интерфейса во время выполнения пользователь должен иметь ресурсную роль entity-log , предоставляемую дополнением Audit.
|
Вы можете настроить журнал сущностей в экране Audit → Entity log. Перейдите на вкладку Setup:

Чтобы создать конфигурацию журнала сущностей, нажмите кнопку Create.
-
Выберите сущность из выпадающего списка Name и выберите атрибуты для аудита.
-
Флажок Auto определяет, регистрирует ли система изменения, когда
EntityLog
вызывается подсистемой JPA при коммите транзакции (с параметромauto = true
). -
Флажок Manual определяет, регистрирует ли система изменения, когда
EntityLog
вызывается кодом приложения (с параметромauto = false
). -
Действия Export и Import позволяют экспортировать и импортировать конфигурации в формате JSON или ZIP.
Также вы можете настроить журнал сущностей, добавив записи в базу данных, если хотите включить конфигурацию в инициализацию базы данных.
Конфигурация логирования включает сущности LoggedEntity
и LoggedAttribute
, которые соответствуют таблицам AUDIT_LOGGED_ENTITY
и AUDIT_LOGGED_ATTR
.
-
LoggedEntity
определяет типы сущностей, которые должны логироваться. -
LoggedAttribute
определяет атрибут сущности для логирования и содержит ссылку наLoggedEntity
и имя атрибута.
Чтобы настроить логирование для конкретной сущности, вставьте соответствующие записи в таблицы AUDIT_LOGGED_ENTITY
и AUDIT_LOGGED_ATTR
.
В следующем примере настройка логирования изменений атрибута phone
сущности Customer
выполняется во время инициализации базы данных:
<changeSet id="1" author="audit">
<insert tableName="AUDIT_LOGGED_ENTITY">
<column name="ID" value="0a6ba81c-a8b9-bc8f-3829-53a6cef48871"/>
<column name="CREATED_BY" value="admin"/>
<column name="CREATE_TS" valueDate="2024-02-21T14:57:25.339"/>
<column name="NAME" value="Customer"/>
<column name="AUTO" value="true"/>
<column name="MANUAL" value="true"/>
</insert>
</changeSet>
<changeSet id="2" author="audit">
<insert tableName="AUDIT_LOGGED_ATTR">
<column name="ID" value="8e6e9825-1381-5299-e704-eadf1b96996e"/>
<column name="CREATE_TS" valueDate="2024-02-21T14:57:25.339"/>
<column name="CREATED_BY" value="admin"/>
<column name="ENTITY_ID" value="0a6ba81c-a8b9-bc8f-3829-53a6cef48871"/>
<column name="NAME" value="phone"/>
</insert>
</changeSet>
Просмотр журнала сущностей
Для доступа к содержимому журнала сущностей перейдите на вкладку View в экране Audit → Entity Log. Настройте необходимые фильтры для поиска конкретных записей журнала.

Дополнительно вы можете получить доступ к записям журнала для конкретной сущности из любого экрана приложения.
Записи журнала хранятся в таблице AUDIT_ENTITY_LOG
, соответствующей сущности EntityLogItem
. Значения измененных атрибутов хранятся в колонке CHANGES
и конвертируются в экземпляры сущности EntityLogAttr
.
В следующем примере экран деталей сущности Order
отображает таблицы данных, содержащие информацию журнала сущностей. Ниже приведен фрагмент XML-дескриптора экрана:
<data>
<instance id="orderDc"
class="com.company.demo.entity.Order">
<fetchPlan extends="_base"/>
<loader/>
</instance>
<collection id="entityLogItemsDc"
class="io.jmix.audit.entity.EntityLogItem"> (1)
<fetchPlan extends="_local"/>
<loader id="entityLogItemsDl" readOnly="true">
<query>
<![CDATA[select e from audit_EntityLog e
where e.entityRef.entityId = :entityOrder]]>
</query>
</loader>
<collection id="entityLogAttrDc" property="attributes"/> (2)
</collection>
</data>
<facets>
<dataLoadCoordinator auto="true"/>
</facets>
<actions>
<action id="saveAction" type="detail_saveClose"/>
<action id="closeAction" type="detail_close"/>
</actions>
<layout>
<formLayout id="form" dataContainer="orderDc">
<datePicker id="dateField" property="date"/>
<textField id="productField" property="product"/>
<textField id="amountField" property="amount"/>
<textField id="priceField" property="price"/>
</formLayout>
<formLayout>
<dataGrid id="entityLogItemsDataGrid"
dataContainer="entityLogItemsDc"> (3)
<columns>
<column property="eventTs"/>
<column property="username"/>
<column property="type"/>
</columns>
</dataGrid>
<dataGrid id="entityLogAttrsDataGrid"
dataContainer="entityLogAttrDc"> (4)
<columns>
<column property="name"/>
<column property="oldValue"/>
<column property="value"/>
</columns>
</dataGrid>
</formLayout>
<hbox id="detailActions">
<button id="saveAndCloseBtn" action="saveAction"/>
<button id="closeBtn" action="closeAction"/>
</hbox>
</layout>
1 | Загрузка коллекции EntityLogItem в контейнер данных entityLogItemsDc . |
2 | Загрузка связанных экземпляров EntityLogAttr в контейнер данных entityLogAttrDc . |
3 | Привязка таблицы данных к контейнеру entityLogItemsDc . |
4 | Привязка таблицы данных к контейнеру entityLogAttrDc . |
Контроллер экрана Order
выглядит следующим образом:
@ViewComponent
private CollectionLoader<EntityLogItem> entityLogItemsDl;
@Subscribe(id = "orderDc", target = Target.DATA_CONTAINER)
public void onOrderDcItemChange(final InstanceContainer.ItemChangeEvent<Order> event) { (1)
entityLogItemsDl.setParameter("entityOrder",event.getItem().getId());
entityLogItemsDl.load();
}
1 | В обработчике события ItemChangeEvent контейнера orderDc параметр устанавливается в зависимый загрузчик, и он запускается. |