3 Replies Latest reply on Jul 15, 2011 11:17 AM by dfisher95350

    Envers hard-coded to ask RevisionEntity for "id" instead of @RevisionNumber?

    dfisher95350

      I'm trying to use a non-PK field for RevisionNumber.  I seem to be very close to succeeding.  Within the transaction (1) the insert of the REVISION row succeeds, (2) the select of the MySQL-generated integer REV_ID (revisionNumber) succeeds, but then the insert of the MYENTITY_AUDIT row fails.  It fails because Envers seems to be hard-coded to ask my RevisionEntity for its "id" instead of its @RevisionNumber when it goes to set the RevisionNumber on MYENTITY_AUDIT. 

       

      My PK entity.id is a String UUID.  I have created another field, called REV_ID in the table and revisionNumber in the Java RevisionEntity.  It is of course an integer.  So, the very last step of my transaction is a type mismatch (data truncated) when trying to insert the mis-obtained String id in place of the integer RevisionNumber.

       

      I've been in the Envers source.  I thought the fix might be as simple as reading a property for revisionNumberPath (which has a hard-coded ".id" appended to it) but it's not that easy, or I am off track.  I would appreciate any help or advice.  It seems so close to working.  (If there is no confiugration solution, I am prepared to alter Envers code in my project, if it comes to that. Even then, I could use some advice. The configuration classes seem fairly complex.)

       

      Where my RevisionEntity (sub-class) contains:

       

      private String id;

      private int revisionNumber;

       

      @Id

      @GeneratedValue(generator = "system-uuid")

      @GenericGenerator(name = "system-uuid", strategy = "uuid")

      @Column(name = "ID")

      public String getId() {

        return id;

      }

       

      public void setId(String id) {

        this.id = id;

      }

         

      @RevisionNumber

      @Generated(GenerationTime.ALWAYS)

      @Column(name = "REV_ID", updatable = false, insertable = false)

      public int getRevisionNumber() {

        return revisionNumber;

      }

       

      public void setRevisionNumber(int revisionNumber) {

        this.revisionNumber = revisionNumber;

      }

       

      Where the MySQL table definition is:

       

      CREATE TABLE REVISION (

          ID CHAR(32) NOT NULL

        , REV_ID INTEGER NOT NULL AUTO_INCREMENT

        , REV_TIMESTAMP BIGINT NOT NULL

        , REV_DETAILS VARBINARY(64000)

        , USER_ID CHAR(32)

        , CONSTRAINT PK_ID PRIMARY KEY (ID)

        , CONSTRAINT UQ_REVID UNIQUE (REV_ID)

      ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

        • 1. Re: Envers hard-coded to ask RevisionEntity for "id" instead of @RevisionNumber?
          dfisher95350

          I have not solved this yet, but I have a new theory, and it may leave me stuck.  First, the revisionNumberPath property appears to be used only to build various read queries.  Second, Envers appears to delegate to Hibernate to create the association between the REVISION table and the MYENTITY_AUDIT table.  Hibernate consults the MYENTITY_AUDIT table meta-data and discovers that ID is the primary key and uses that.  (Envers names the target field on MYENTITY_AUDIT as whatever I have configured as RevisionNumber field [REV_ID in my case], but nonetheless hands it off to Hibernate as a relationship via that field.  Note, I have not defined a FK relationship in my DDL.)

           

          That's my working theory right now, and if correct, I may be stuck.  (I am willing to change some Envers code, but not a lot of it.)

           

          Perhaps Hibernate would interpret the meta-data differently if I modeled the FK relationship (if my theory is even on the right path).

          • 2. Envers hard-coded to ask RevisionEntity for "id" instead of @RevisionNumber?
            adamw

            Hello,

             

            yes, that's true, all of the audit entities have a relation to the RevisionEntity entity, plus it's used in read queries.

            But in fact, to implement your use-case correctly, don't you think that the audit entities should still have a relation to the RevisionEntity based on the PK (so in the audit tables, you would have the UUIDs)? And the revision number would be used only for reading?

             

            Unless I'm missing some vital point I think it should work

             

            Adam

            • 3. Re: Envers hard-coded to ask RevisionEntity for "id" instead of @RevisionNumber?
              dfisher95350

              Thanks Adam. It's been a few weeks, but indeed, I think was trying to maintain the relationship via RevisionNumber in both tables, perhaps out of an assumption that it had to be there.  I may return to the problem and see if Envers will work if I make the cleaner PK relationship you recommend.