Журнал сущностей
Журнал сущностей - это механизм для отслеживания изменений, вносимых в 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параметр устанавливается в зависимый загрузчик, и он запускается. |