1 Reply Latest reply on May 30, 2013 3:50 AM by hltbdivl

    Validity audit strategy with ID reuse = db corruption

    hltbdivl

      I've been working on a deployment of Envers for configuration history tracking and have run into a serious bug with the validity audit strategy.

       

      We're using increment generators for our entities; this corresponds to the IncrementGenerator class in the Hibernate code. This class initializes an ID counter in memory based on the highest ID currently in the database plus one, incrementing the in-memory counter in every subsequent use. Should the class be reset (e.g. restarting the application, rebuilding the EntityManagerFactory, etc.), the generator's counter will again be set to the last ID plus one. So as you can see, in some cases we might reuse an ID that was used for a past entity that has since been deleted.

       

      The validity audit strategy doesn't handle ID reuse like this properly. From ValidityAuditStrategy.perform():

       

      {code}

      // Update the end date of the previous row if this operation is expected to have a previous row

      if (getRevisionType(auditCfg, data) != RevisionType.ADD) {

        ...

      }

      {code}

       

      The problem is that we don't update past audit entries if we're persisting an ADD. This is wrong; we'll persist an ADD the first time we reuse an unused ID, and we need to find the last DEL corresponding to this entity's ID (if it exists) and update its REVEND. Otherwise future attempts to update this new entity will fail, because ValidityAuditStrategy.perform() will return two rows whose REVEND can be updated: the DEL belonging to the previous (deleted) entity, and the ADD we just persisted for the new entity.

       

      I couldn't find a bug report in JIRA but I'd happy to file one if folks agree this is a real bug.