Entity Log
Entity Log is a mechanism for monitoring changes made to JPA entities. It records changes in entity attributes and provides a user interface for querying and displaying details regarding the changes:
-
What entity instance was changed.
-
Old and new values of changed attributes.
-
When the entity was changed.
-
Which user changed the entity.
Registering Changes
Entity Log automatically records changes made to JPA entities upon transaction commit when working with DataManager or EntityManager. It is not operational when native SQL is used.
Also, if you load entities by EntityManager
, you can use the EntityLog
bean directly to log changes in entities from your application code. In this case, invoke registerCreate()
, registerModify()
and registerDelete()
methods with the auto
parameter set to false
. When the entity log is called automatically by the framework, this parameter is set to true
.
EntityLog can register changes only when used for managed entities inside a transaction. It means that you should invoke EntityLog from application code only if you use EntityManager for loading data. Entities loaded with DataManager are always detached and their changes cannot be registered by invoking EntityLog manually.
|
Setting Up Entity Log
To be able to use the administrative UI at runtime, a user must have the entity-log resource role provided by the Audit add-on.
|
You can configure the entity log in the Audit → Entity Log view. Switch to the Setup tab:

To establish entity log configuration, click the Create button.
-
Choose the entity from the Name drop-down list and select the attributes for auditing.
-
The Auto checkbox determines whether the system logs changes when
EntityLog
is invoked by the JPA subsystem on transaction commit (withauto = true
parameter). -
The Manual checkbox determines whether the system logs changes when
EntityLog
is invoked by application code (withauto = false
parameter). -
The Export and Import actions allow you to export and import configurations in JSON or ZIP format.
Also, you can set up entity log by entering some records in the database if you want to include the configuration to the database initialization.
Logging configuration involves the LoggedEntity
and LoggedAttribute
entities, which correspond to the AUDIT_LOGGED_ENTITY
and AUDIT_LOGGED_ATTR
tables.
-
LoggedEntity
specifies the entity types to be logged. -
LoggedAttribute
defines the entity attribute to be logged and contains a link to theLoggedEntity
and the attribute name.
To configure logging for a specific entity, insert the corresponding entries into the AUDIT_LOGGED_ENTITY
and AUDIT_LOGGED_ATTR
tables.
In the following example, logging changes to the phone
attribute of the Customer
entity is configured during database initialization:
<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>
Viewing Entity Log
To access the content of the entity log, navigate to the View tab within the Audit → Entity Log view. Configure the required filters to locate specific log entries.

Additionally, you can access the log entries for a particular entity from any application view.
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 following example, an Order
detail view displays data grids containing the entity log information. Below is an excerpt from the view’s XML descriptor:
<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 | Loading a collection of EntityLogItem into the entityLogItemsDc data container. |
2 | Loading associated EntityLogAttr instances into the entityLogAttrDc data container. |
3 | Binding a data grid to the entityLogItemsDc container. |
4 | Binding a data grid to the entityLogAttrDc container. |
Order
view controller looks like this:
@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 | In the ItemChangeEvent handler of the orderDc container, a parameter is set to the dependent loader and it is triggered. |