7

Our Java app is Spring based and we have domain classes and the corresponding schema generated via Liquibase.

We are planning to add support for a single domain to be audited.

a. We don't have hibernate.xml and hibernate.cfg.xml instead we are using application-context.xml. Then how do I create audit table through annotations like @Audited.

How do I solve this issue? I have added hibernate configuration as

<property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</prop>
                <prop key="hibernate.ejb.event.post-insert">org.hibernate.ejb.event.EJB3PostInsertEventListener,org.hibernate.envers.event.AuditEventListener</prop>
                <prop key="hibernate.ejb.event.post-update">org.hibernate.ejb.event.EJB3PostUpdateEventListener,org.hibernate.envers.event.AuditEventListener</prop>
                <prop key="hibernate.ejb.event.post-delete">org.hibernate.ejb.event.EJB3PostDeleteEventListener,org.hibernate.envers.event.AuditEventListener</prop>
                <prop key="hibernate.ejb.event.pre-collection-update">org.hibernate.envers.event.AuditEventListener</prop>
                <!-- <prop key="hibernate.ejb.event.pre-collection-remove">org.hibernate.envers.event.AuditEventListener</prop>
                <prop key="hibernate.ejb.event.post-collection-recreate">org.hibernate.envers.event.AuditEventListener</prop> -->
                <prop key="org.hibernate.envers.revision_field_name">REV</prop>
                <prop key="org.hibernate.envers.revision_type_field_name">REVTYPE</prop>
                <prop key="org.hibernate.envers.auditTablePrefix"></prop>
                <prop key="org.hibernate.envers.auditTableSuffix">_AUD</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
                <prop key="hibernate.show_sql">true</prop>
            </props>
        </property>

Added @Audited annotation in my domain class

@Entity
@Audited
@Table(name="user")
public class User implements Serializable {

But this configuration did not create audit tables in the development environment. Its not clear what additional configuration I am missing here.

b. How should I create the necessary envers specific schema using Liquibase, the production team is not comfortable with the idea of auto generating the SQL schema as well in the production environment.

SST
  • 2,054
  • 5
  • 35
  • 65
  • You can manually create the Audit tables when using Envers. So i guess you need to add configuration to liquibase to create those tables. – Rohit Jan 21 '15 at 06:31
  • Thanks for your reply!! If I create audit table manually then how do I getting populate while updating any fields in the original table? – SST Jan 21 '15 at 13:35
  • 1
    Which Hibernate version are you using? With 4, you don't need any special config to enable auditing, just adding the jar is enough. – adamw Jan 22 '15 at 08:00
  • we are using hibernate version: 3.6.3.Final – SST Jan 22 '15 at 08:44

1 Answers1

3

I use in our project Hibernate, Envers and Liquibase.

The solution to add envers to the entity ExampleEntitity with db table exampleEntitity (only table, if it is simple entity and we don't audit relations):

First, add to liquibase <changeSet> tags eg.:

<changeSet author="Gal" id="createExampleEntitity_AUD">
    <createTable tableName="exampleEntitity_AUD">
        <column name="id" type="BIGINT">
            <constraints nullable="false"/>
        </column>
        <column name="REV" type="BIGINT">
            <constraints nullable="false"/>
        </column>
        <column name="REVTYPE" type="SMALLINT"/>
        (...)
    </createTable>
</changeSet>

<changeSet author="Gal" id="primaryKeyExampleEntitity_AUD">
    <addPrimaryKey columnNames="id, REV" tableName="exampleEntitity_AUD"/>
</changeSet>

<changeSet author="Gal" id="fkExampleEntitity_AUD_revisionsTable">
    <addForeignKeyConstraint baseColumnNames="REV" baseTableName="exampleEntitity_AUD" 
        constraintName="FK_revisions_exampleEntitity_AUD" 
        deferrable="false" initiallyDeferred="false" 
        onDelete="NO ACTION" onUpdate="NO ACTION" 
        referencedColumnNames="id" referencedTableName="revisionsTable"/>
</changeSet>

id, (...) -> fields from table exampleEntitity, which you want to audit.

Second, add @Audited adnotation to entity ExampleEntitity (or @Audited(targetAuditMode = RelationTargetAuditMode.NOT_AUDITED) if you dont want to audit related entities).

That's all. Now all changes of instances ExampleEntitity will be stored in table exampleEntitity_AUD.

WGawel
  • 72
  • 6