This is an internal documentation. There is a good chance you’re looking for something else. See Disclaimer.
Entity History Implementation¶
In order for this to work properly it needs to be loaded eagerly (
hiveapp.EagerLoad contribution) so that the
service can register itself with the ContextManager when the application
Whenever a new Context is created, several listeners will be added to the new context (all these listeners are removed again when the context is closed):
This listener is an EntityFacadeListener, which will be notified about all entity changes during a transaction.
Every entity that is modified during the transaction is stored in the context attribute
Before the entity is stored, it is checked whether it should be included in the history using the
HistoryConfiguration (a particular entity model
might be excluded from the history or the history might be disabled entirely).
prepareCommit method of the TransactionAware is called
after all other listeners have already ran, so we can be sure that all changes have been captured by the
HistoryEntityFacadeListener at this point.
All entities that have been saved in the
history-snapshots-entities attribute will be converted
into a DetachedEntity, which contains all necessary information
for the snapshot that will be saved to the database. This has to be done before the commit, as some information is no longer available after commit
(changed fields for example).
Which fields and relations will be included in the snapshot depends on the entity model and is defined by the HistoryConfiguration.
All the created DetachedEntity are stored in the context attribute
history-snapshots-entities will be removed at this point).
This CommitListener is executed after the transaction is committed
(to make sure that the history is only written when the transaction has been committed successfully).
All the DetachedEntity instances are read from the context attribute
and converted to an XML format using the XStream library. The generation of the XML is always executed in the null business unit.
The XML structure is defined in the DetachedEntityMarshaller
and is exactly the same as in the previous history implementation (in order to be compatible with older history entries).
The XML String is gzipped before it is saved to save storage space.
The compressed XML data (along with other data like the username and ip address) are passed to the HistoryDataStore where they are persisted in a dedicated history postgresql database. This is done asynchronously in a separate thread for performance reasons.
The HistoryConfiguration contains all information whether the history is enabled for a certain entity model and if yes, which fields and relations should be included.
The history can be globally disabled using the
In addition it can also be disabled for specific entity models using the
Obviously no history entries will be created for session-only entities.
Which fields and relations are included in the snapshot is controlled by the EntityHistoryConfiguration.
There are default implementations for standard (DefaultEntityHistoryConfig)
and lookup entities (LookupEntityHistoryConfig).
IgnoredEntityModels contribution mentioned above can also be used the further refine the default implementations
by removing certain fields and relations from the snapshot.
However it is also possible to completely customize the history snapshot with a custom implementation (see PageEntityHistoryConfiguration for example).