简体   繁体   中英

Retrieve Revisions of Mapping Tables - Hibernate Envers

I'm using Hibernate with Envers, 4.3.6 FINAL. I have set up auditing using the annotations, and all of my audit tables have been created and are being populated correctly when I save information in my application. One of my audited entities has a mapping table to additional entities, with a @ManyToMany configuration.

Employer -> Designations

The employer can have 0 to n Designation entities associated with it. The mapping table is standard, just having two columns, a foreign key to the Employers table and a foreign key to the Designations table. Envers created an auditing table for this mapping table and records are appropriately recorded, with inserts or deletes entered with the same REV as the Employer when the Employer is edited.

What I'm trying to do now is retrieve the audit information from the database so I can present it for reporting purposes. Retrieving the list of revisions for my Employer is working and the state of the Employer for a given revision is accurate. What I haven't been able to figure out is how to retrieve the audits for the mapping table. I have no actual entity for these pairings. They are put together using the javax.persistence.JoinTable annotation. As such, there's no record for an entity in my REVCHANGES table (I'm setting org.hibernate.envers.track_entities_changed_in_revision to true). Looking at the database, there are records for my EmployerDesignations mapping table and the corresponding EmployerDesignations_AUD audit table, but I don't know how to retrieve these audit records nor how to even know when they have been changed for a given revision.

How can the audit history for a mapping table be retrieved?

Employer class:

@Entity
@DynamicInsert
@DynamicUpdate
@SelectBeforeUpdate
@Table(name="EMPLOYERS")
@Audited
public class Employer implements Serializable {

    //All other fields omitted for brevity
    ...

    private List<Designations> designations;
    @ManyToMany
    @JoinTable(name = "EMPLOYERDESIGNATIONS", 
        joinColumns =           { @JoinColumn(name = "FK_EMPLOYER", nullable = false) },
        inverseJoinColumns =    { @JoinColumn(name = "FK_DESIGNATION", nullable = false) })
    public List<Designations> getDesignations() {
        return designations;
    }
    public void setDesignations(List<Designations> designations) {
        this.designations= designations;
    }
}

Designation class:

@Entity
@DynamicInsert
@DynamicUpdate
@SelectBeforeUpdate
@Table(name="DESIGNATIONS")
@Audited
public class Designation implements Serializable {

    //All other fields omitted for brevity
    ...

    private List<Employer> employers;
    @ManyToMany
    @JoinTable(name = "EMPLOYERDESIGNATIONS", 
        joinColumns =           { @JoinColumn(name = "FK_DESIGNATION", nullable = false) },
        inverseJoinColumns =    { @JoinColumn(name = "FK_EMPLOYER", nullable = false) })
    public List<Employer> getEmployers() {
        return employers;
    }
    public void setEmployers(List<Employer> employers) {
        this.employers= employers;
    }
}

Test Code for audit data retrieval:

List<Number> revisions = reader.getRevisions(Employer.class, employerId);
System.out.println(revisions);
for (Number revisionNum : revisions) {
    Employer employer = reader.find(Employer.class, employerId, revisionNum);
    System.out.println(employer);
}

All you need to do is to retrieve the Employer instance and then simply access the getter for the association and whatever state that associated had when the entity was audited will be made available automatically.

If we assume the first operation in the Envers environment was you creating an Employer and associating it with two Designation entities via your join, then when you fetch the Employer instance for revision 1, the collection would have two elements.

Later on in transaction 2, you modify Employer and you remove one Designation and add a new Designation to the entity, then when you fetched the Employer at revision 2, it would still contain two Designation entity instances, but those instances would be the one that remained from the first revision and the second which you added as part of the second revision.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM