Viewing Entity Log

To view the entity log content, go to the Administration → Entity Log screen. Set necessary filters to find log entries.

entity log view

Also, you can access the log for a certain entity from any application screen.

Log entries are stored in the AUDIT_ENTITY_LOG table corresponding to the EntityLogItem entity. Changed attribute values are stored in the CHANGES column and are converted to instances of EntityLogAttr entity.

In the example below, an edit screen for the Order entity shows tables with the entity log content.

Here is a fragment of the screen XML descriptor:

<data>
    <instance id="orderDc"
              class="audit.ex1.entity.Order">
        <fetchPlan extends="_local"/>
        <loader id="orderDl"/>
    </instance>
    <collection id="entityLogItemsDc"
                class="io.jmix.audit.entity.EntityLogItem"> (1)
        <fetchPlan extends="_local"/>
        <loader id="entityLogItemsDl">
            <query>
                <![CDATA[select e from audit_EntityLog e
                        where e.entityRef.entityId = :order
                        order by e.eventTs]]>
            </query>
        </loader>
        <collection id="entityLogAttrDc" property="attributes"/> (2)
    </collection>
</data>
<facets>
    <dataLoadCoordinator auto="true"/>
</facets>
<dialogMode height="600"
            width="800"/>
<layout spacing="true" expand="editActions">
    <vbox spacing="true">
        <form id="form" dataContainer="orderDc">
            <column width="350px">
                <dateField id="dateField" property="date"/>
                <textField id="productField" property="product"/>
                <textField id="amountField" property="amount"/>
            </column>
        </form>
        <hbox spacing="true">
            <table id="logTable"
                   width="100%"
                   height="100%"
                   dataContainer="entityLogItemsDc"> (3)
                <columns>
                    <column id="eventTs"/>
                    <column id="userLogin"/>
                    <column id="type"/>
                </columns>
            </table>
            <table id="attrTable"
                   height="100%"
                   width="100%"
                   dataContainer="entityLogAttrDc"> (4)
                <columns>
                    <column id="name"/>
                    <column id="oldValue"/>
                    <column id="value"/>
                </columns>
            </table>
        </hbox>
    </vbox>
    <hbox id="editActions" spacing="true">
        <button id="commitAndCloseBtn" action="windowCommitAndClose"/>
        <button id="closeBtn" action="windowClose"/>
    </hbox>
</layout>
1 Loading a collection of EntityLogItem into the entityLogItemsDc data container.
2 Loading associated EntityLogAttr instances into the entityLogAttrDc data container.
3 A table connected to the entityLogItemsDc container.
4 A table connected to the entityLogAttrDc container.

Order screen controller looks like this:

@Autowired
private InstanceLoader<Order> orderDl;
@Autowired
private CollectionLoader<EntityLogItem> entityLogItemsDl;

@Subscribe
public void onBeforeShow(BeforeShowEvent event) { (1)
    orderDl.load();
}

@Subscribe(id = "orderDc", target = Target.DATA_CONTAINER)
public void onOrderDcItemChange(InstanceContainer.ItemChangeEvent<Order> event) { (2)
    entityLogItemsDl.setParameter("order", event.getItem().getId());
    entityLogItemsDl.load();
}
1 The onBeforeShow method loads data before showing the screen.
2 In the ItemChangeEvent handler of the orderDc container, a parameter is set to the dependent loader and it is triggered.