Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate - Envers -> auditing / versioning of an attribute, but only if the value changed

I have a problem with Hibernate - Envers. I have a domain object with only one audited attribute status which can be one of the numbers 0,1,2,3,4,5.

@Entity
public class Item {
    ...
    @Audited
    private int status;
    ... other variables, setter/getter, ...
}

Now, everything in Envers and Hibernate is working. Creating a new Item object and add it to the database a row is inserted into theItem_AUD database table.

But now I have a problem with updating it. My update in the Hibernate Dao implementation looks like:

public void updateItem(Item i) {
    SessionFactory sessionFac = HibernateUtility.getSessionFactory();
    Session s = sessionFac.getCurrentSession();
    Transaction trans = s.beginTransaction();
    s.update(i);
    s.flush();
    trans.commit();
}

On every update, this is printed on my console:

Hibernate: update Item set amount=?, description=?, status=? where id=?
Hibernate: insert into REVINFO (REVTSTMP) values (?)
Hibernate: insert into Item_AUD (REVTYPE, status, id, REV) values (?, ?, ?, ?)

But the problem is, that I only want to insert a row into the REVINFO and Item_AUD if the status number has changed!

For example: I change the description of the item, perform the update with calling updateItem and then Envers write a new revision to the auditing tables. But I do not want this behavior.

What I want: only if the value of status is changed, Envers should write database entries into the auditing tables.

But how can I do this?

Best Regards, Tim.

like image 418
Tim Avatar asked Jan 05 '11 09:01

Tim


People also ask

How Hibernate Envers works?

Hibernate Envers provides a very simple solution for CDC (Change Data Capture). It uses the Hibernate Event system to intercept all entity state transitions and audit them. The database transaction will roll back and both the actual changes and the audit log is rolled back.

What is Hibernate Envers?

The Envers module is a core Hibernate model that works both with Hibernate and JPA. In fact, you can use Envers anywhere Hibernate works whether that is standalone, inside WildFly or JBoss AS, Spring, Grails, etc. The Envers module aims to provide an easy auditing / versioning solution for entity classes.

What is @NotAudited?

NotAudited means "I just don't care for this field in historical data" (it won't be saved, relationship will be null, you won't see it when looking historical data about CustomerBooking ) Follow this answer to receive notifications.


1 Answers

For this, you have to extend AuditEventListener & override its methods.

    public class EnversListener extends AuditEventListener {

      @Override
      public void onPostInsert(PostInsertEvent event) {

        Object o = event.getEntity();

        if (o instanceof Item) {

          Item currentItem = (Item) o;
          Item previousItem = findItemById(currentItem.getId());

          if(previousItem != null)
              if (currentItem.getStatus() != previousItem.getStatus()) 
                 super.onPostInsert(event);

        } else {
          super.onPostInsert(event);
        }
      }

      @Override
      public void onPostDelete(PostDeleteEvent event) {
        super.onPostDelete(event);
      }

      @Override
      public void onPostRecreateCollection(PostCollectionRecreateEvent event) {
        super.onPostRecreateCollection(event);
      }

      @Override
      public void onPostUpdate(PostUpdateEvent event) {
          super.onPostUpdate(event);
      }

      @Override
      public void onPreRemoveCollection(PreCollectionRemoveEvent event) {
        super.onPreRemoveCollection(event);
      }

      @Override
      public void onPreUpdateCollection(PreCollectionUpdateEvent event) {
        super.onPreUpdateCollection(event);
      }
}

You can add custom constraints in the other overridden methods as required. The path to the listener class inside hibernate.cfg.xml should be configured accordingly.

like image 62
Nayan Wadekar Avatar answered Sep 23 '22 16:09

Nayan Wadekar