4 Replies Latest reply on Jun 21, 2010 10:31 AM by Florian Haupt

    Using Envers for Detecting Changes

    Florian Haupt Newbie

      Hi!


      i am extending an existing application that was built using SEAM, Hibernate and Envers. It looks like:


      persistence.xml:


      <persistence-unit name="xyz" transaction-type="JTA">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <jta-data-source>java:/xyzDatasource</jta-data-source>
        <jar-file>xyz-model.jar</jar-file>
        
        <class>de.xyz.entity.SomeEntity</class>
        ...
      
        <properties>
          ...
          <property name="hibernate.ejb.event.post-insert"
                    value="org.hibernate.envers.event.AuditEventListener" />
          ...
        </properties>
      </persistence-unit>



      SomeEntity.java:


      @Entity
      @Table(name = "SomeTableName")
      @Audited
      @Indexed
      @EntityListeners(TestListener.class)
      public class SomeEntity {
        ...
      }
      



      As you see, everything is configured to realize persistence and versioning of all entities.


      My work is now to detect changes (new entity, deleted entity, changend entity) that occur in the application. Versioning is activated by envers, but how to use it?


      I can register listeners (e.g. @PostUpdate), but how do i access the version information from envers?


      I would like to do something like:


      @PostUpdate
      public void postUpdate(){
        Object entityAfterUpdate = this;
        Object entityBeforeUpdate = getFromEnvers(revisionBeforeUpdate); // <- how to do that?
        // here comes further application logic, compare both objects, detect changes...
      }
      
      @PostRemove
      public void PostRemove(){
        System.out.println("entity deleted: "+this);
      }
      
      ...
      



      Any help is welcome!

        • 1. Re: Using Envers for Detecting Changes
          Leo van den berg Master

          Hi,


          maybe helpful for you. The following is a piece of code which detects changes between the status of (traffic) incidents. It reads the actual and previous version of the incident and provides to a specific part of a workflow where we look at different attributes.
          It uses a unique code of the incident to retrieve it.


          ...
          try {
               AuditReader reader = AuditReaderFactory.get(entityManager);
               AuditQuery aq = reader.createQuery().forRevisionsOfEntity(
                                   TrafficIncident.class, true, false);
               List list = aq.addOrder(AuditEntity.revisionNumber().desc())
                         .add(AuditEntity.property("uniqueCode").eq(code))
                         .setMaxResults(2).getResultList();
          
               if (list.size() == 1){
                 actualIncident = (TrafficIncident) list.get(0);
                    previousIncident = null;
               } else if (list.size() == 2){
                    actualIncident = (TrafficIncident) list.get(0);
                    previousIncident = (TrafficIncident) list.get(1);
               }
                              
               } catch (WhateverException e) {
                    log.error("AUDIT ACCESS DOESN'T WORK!! IF YOU GET HERE", e);
               } 




          You need to look up the rest in the envers doc, which is not great but sufficient. Try to find the Seam7Envers example. Which let you put additional context data in the audit tables.


          Leo



          • 2. Re: Using Envers for Detecting Changes
            Florian Haupt Newbie

            Hi Leo,


            yes, i think this will be helpful. Thanks!


            There remains one fundamental question concerning your code example:
            Where / How do i get the entityManager?

            • 3. Re: Using Envers for Detecting Changes
              Leo van den berg Master

              Hi,


              Just inject it in your bean e.g.




              @In EntityManager entityManager;



              ... or whatever name you have given to the entity manager in components.xml


              Leo

              • 4. Re: Using Envers for Detecting Changes
                Florian Haupt Newbie

                ok, got it


                in my project, the EntityManager is registered in JNDI, so i got to get it from there. It seems to work now, thanks for your help!