Hibernate.orgCommunity Documentation

Chapter 7. Generated tables and their content

For each audited entity (that is, for each entity containing at least one audited field), an audit table is created. By default, the audit table's name is created by adding a "_AUD" suffix to the original name, but this can be overriden by specifing a different suffix/prefix (see Chapter 3, Configuration) or on a per-entity basis using the @AuditTable annotation.

The audit table has the following fields:

  1. id of the original entity (this can be more then one column, if using an embedded or multiple id)

  2. revision number - an integer

  3. revision type - a small integer

  4. audited fields from the original entity

The primary key of the audit table is the combination of the original id of the entity and the revision number - there can be at most one historic entry for a given entity instance at a given revision.

The current entity data is stored in the original table and in the audit table. This is a duplication of data, however as this solution makes the query system much more powerful, and as memory is cheap, hopefully this won't be a major drawback for the users. A row in the audit table with entity id ID, revision N and data D means: entity with id ID has data D from revision N upwards. Hence, if we want to find an entity at revision M, we have to search for a row in the audit table, which has the revision number smaller or equal to M, but as large as possible. If no such row is found, or a row with a "deleted" marker is found, it means that the entity didn't exist at that revision.

The "revision type" field can currently have three values: 0, 1, 2, which means, respectively, ADD, MOD and DEL. A row with a revision of type DEL will only contain the id of the entity and no data (all fields NULL), as it only serves as a marker saying "this entity was deleted at that revision".

Additionaly, there is a "REVINFO" table generated, which contains only two fields: the revision id and revision timestamp. A row is inserted into this table on each new revision, that is, on each commit of a transaction, which changes audited data. The name of this table can be configured, as well as additional content stored, using the @RevisionEntity annotation, see Chapter 4, Logging data for revisions.

While global revisions are a good way to provide correct auditing of relations, some people have pointed out that this may be a bottleneck in systems, where data is very often modified. One viable solution is to introduce an option to have an entity "locally revisioned", that is revisions would be created for it independently. This wouldn't enable correct versioning of relations, but wouldn't also require the "REVINFO" table. Another possibility if to have "revisioning groups", that is groups of entities which share revision numbering. Each such group would have to consist of one or more strongly connected component of the graph induced by relations between entities. Your opinions on the subject are very welcome on the forum! :)