Entity Snapshots

The entity snapshots saving mechanism, as well as the entity log, is intended to track data changes at runtime. It has the following distinct features:

  • The whole state (or snapshot) of a graph of entities defined by a specified fetchPlan is saved.

  • Snapshot saving mechanism is explicitly called from the application code.

  • The framework allows the snapshots to be viewed and compared.

Saving Snapshots

To save a snapshot of a given graph of entities, you need to call the EntitySnapshotService.createSnapshot() method and pass it the entity, which is an entry point to the graph, and the fetchPlan describing the graph. The snapshot will be created using the loaded entities without any calls to the database. As a result, the snapshot will not contain the fields that are not included in the fetchPlan used to load the entity.

The graph of Java objects is converted into XML and saved in the AUDIT_ENTITY_SNAPSHOT table (corresponding to the EntitySnapshot entity) together with the link to the primary entity.

Usually, snapshots need to be saved after the editor screen commit. This may be achieved by creating the AfterCommitChangesEvent listener of the screen controller, for example:

@Autowired
protected EntitySnapshotManager entitySnapshotManager;

@Subscribe
protected void onAfterCommitChanges(AfterCommitChangesEvent event) {
    entitySnapshotManager.createSnapshot(getEditedEntity(),
            getEditedEntityContainer().getFetchPlan());
}

Viewing Snapshots

Viewing snapshots for arbitrary entities is possible using the snapshotDiff fragment. For example:

<fragment id="snapshotDiff"
          width="100%"
          height="100%"
          screen="snapshotDiff"/>

The snapshots should be loaded into the fragment from the edit screen controller:

@Autowired
protected EntityStates entityStates;

@Autowired
protected SnapshotDiffViewer snapshotDiff;

@Subscribe
protected void onBeforeShow(BeforeShowEvent event) {
    if (!entityStates.isNew(getEditedEntity())) {
        snapshotDiff.loadVersions(getEditedEntity());
    }
}

The snapshotDiff fragment shows the list of snapshots for the given entity, with the ability to compare them. The fetchPlan for each snapshot includes the user, date, and time. When a snapshot is selected from the list, the changes will be displayed compared to the previous snapshot. All attributes are marked as changed for the first snapshot. Selecting two snapshots shows the results of the comparison in a table.

The comparison table shows attribute names and their new values. When a row is selected, detailed information on attribute changes across two snapshots is shown. Reference fields are displayed according to their instance name. When comparing collections, the new and removed elements are highlighted with green and red colors, respectively. Collection elements with changed attributes are displayed without highlighting. Changes to element positions are not recorded.