Hibernate.orgCommunity Documentation

Chapter 3. Configuration

3.1. Basic configuration
3.2. Choosing an audit strategy
3.3. Reference

To start working with Envers, all configuration that you must do is add the event listeners to persistence.xml, as described in the Chapter 1, Quickstart.

However, as Envers generates some entities, and maps them to tables, it is possible to set the prefix and suffix that is added to the entity name to create an audit table for an entity, as well as set the names of the fields that are generated.

After the basic configuration it is important to choose the audit strategy that will be used to persist and retrieve audit information. There is a trade-off is between the performance of persisting and the performance of querying the audit information. Currently there two audit strategies:

In more detail, here are the properties that you can set:

Table 3.1. Envers Configuration Properties

Property nameDefault valueDescription
org.hibernate.envers.audit_table_prefix String that will be prepended to the name of an audited entity to create the name of the entity, that will hold audit information.
org.hibernate.envers.audit_table_suffix _AUD String that will be appended to the name of an audited entity to create the name of the entity, that will hold audit information. If you audit an entity with a table name Person, in the default setting Envers will generate a Person_AUD table to store historical data.
org.hibernate.envers.revision_field_name REV Name of a field in the audit entity that will hold the revision number.
org.hibernate.envers.revision_type_field_name REVTYPE Name of a field in the audit entity that will hold the type of the revision (currently, this can be: add, mod, del).
org.hibernate.envers.revision_on_collection_change true Should a revision be generated when a not-owned relation field changes (this can be either a collection in a one-to-many relation, or the field using "mappedBy" attribute in a one-to-one relation).
org.hibernate.envers.do_not_audit_optimistic_locking_field true When true, properties to be used for optimistic locking, annotated with @Version, will be automatically not audited (their history won't be stored; it normally doesn't make sense to store it).
org.hibernate.envers.store_data_at_delete false Should the entity data be stored in the revision when the entity is deleted (instead of only storing the id and all other properties as null). This is not normally needed, as the data is present in the last-but-one revision. Sometimes, however, it is easier and more efficient to access it in the last revision (then the data that the entity contained before deletion is stored twice).
org.hibernate.envers.default_schema null (same as normal tables) The default schema name that should be used for audit tables. Can be overriden using the @AuditTable(schema="...") annotation. If not present, the schema will be the same as the schema of the normal tables.
org.hibernate.envers.default_catalog null (same as normal tables) The default catalog name that should be used for audit tables. Can be overriden using the @AuditTable(catalog="...") annotation. If not present, the catalog will be the same as the catalog of the normal tables.
org.hibernate.envers.audit_strategy org.hibernate.envers.strategy.DefaultAuditStrategy The audit strategy that should be used when persisting audit data. The default stores only the revision, at which an entity was modified. An alternative, the org.hibernate.envers.strategy.ValidityAuditStrategy stores both the start revision and the end revision. Together these define when an audit row was valid, hence the name ValidityAuditStrategy.
org.hibernate.envers.audit_strategy_validity_end_rev_field_name REVEND The column name that will hold the end revision number in audit entities. This property is only valid if the validity audit strategy is used.
org.hibernate.envers.audit_strategy_validity_store_revend_timestamp false Should the timestamp of the end revision be stored, until which the data was valid, in addition to the end revision itself. This is useful to be able to purge old Audit records out of a relational database by using table partitioning. Partitioning requires a column that exists within the table. This property is only evaluated if the ValidityAuditStrategy is used.
org.hibernate.envers.audit_strategy_validity_revend_timestamp_field_name REVEND_TSTMP Column name of the timestamp of the end revision until which the data was valid. Only used if the ValidityAuditStrategy is used, and org.hibernate.envers.audit_strategy_validity_store_revend_timestamp evaluates to true

Important

The following configuration options have been added recently and should be regarded as experimental:

  1. org.hibernate.envers.audit_strategy
  2. org.hibernate.envers.audit_strategy_validity_end_rev_field_name
  3. org.hibernate.envers.audit_strategy_validity_store_revend_timestamp
  4. org.hibernate.envers.audit_strategy_validity_revend_timestamp_field_name

To change the name of the revision table and its fields (the table, in which the numbers of revisions and their timestamps are stored), you can use the @RevisionEntity annotation. For more information, see Chapter 4, Logging data for revisions.

To set the value of any of the properties described above, simply add an entry to your persistence.xml. For example:

<persistence-unit ...>
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>...</class>
<properties>
   <property name="hibernate.dialect" ... />
   <!-- other hibernate properties -->

   <property name="hibernate.ejb.event.post-insert"
             value="org.hibernate.ejb.event.EJB3PostInsertEventListener,org.hibernate.envers.event.AuditEventListener" />
   <property name="hibernate.ejb.event.post-update"
             value="org.hibernate.ejb.event.EJB3PostUpdateEventListener,org.hibernate.envers.event.AuditEventListener" />
   <property name="hibernate.ejb.event.post-delete"
             value="org.hibernate.ejb.event.EJB3PostDeleteEventListener,org.hibernate.envers.event.AuditEventListener" />
   <property name="hibernate.ejb.event.pre-collection-update"
             value="org.hibernate.envers.event.AuditEventListener" />
   <property name="hibernate.ejb.event.pre-collection-remove"
             value="org.hibernate.envers.event.AuditEventListener" />
   <property name="hibernate.ejb.event.post-collection-recreate"
             value="org.hibernate.envers.event.AuditEventListener" />

   <property name="org.hibernate.envers.versionsTableSuffix" value="_V" />
   <property name="org.hibernate.envers.revisionFieldName" value="ver_rev" />
   <!-- other envers properties -->
</properties>
</persistence-unit>

The EJB3Post...EvenListeners are needed, so that ejb3 entity lifecycle callback methods work (@PostPersist, @PostUpdate, @PostRemove.

You can also set the name of the audit table on a per-entity basis, using the @AuditTable annotation. It may be tedious to add this annotation to every audited entity, so if possible, it's better to use a prefix/suffix.

If you have a mapping with secondary tables, audit tables for them will be generated in the same way (by adding the prefix and suffix). If you wish to overwrite this behaviour, you can use the @SecondaryAuditTable and @SecondaryAuditTables annotations.

If you'd like to override auditing behaviour of some fields/properties in an embedded component, you can use the @AuditOverride(s) annotation on the place where you use the component.

If you want to audit a relation mapped with @OneToMany+@JoinColumn, please see Chapter 10, Mapping exceptions for a description of the additional @AuditJoinTable annotation that you'll probably want to use.

If you want to audit a relation, where the target entity is not audited (that is the case for example with dictionary-like entities, which don't change and don't have to be audited), just annotate it with @Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED). Then, when reading historic versions of your entity, the relation will always point to the "current" related entity.

If you'd like to audit properties encapsulated by any subset of your entity's mapped superclasses (which are not explicitly audited), list desired supertypes in auditParents attribute of @Audited annotation. If any @MappedSuperclass (or any of it's properties) is marked as @Audited, it's behavior is implicitly inherited by all audited subclasses.