Ujjwal Pathak
Ujjwal Pathak

Reputation: 686

How to query RevisionEntity in hibernate envers

I was trying to log additional user data with the revisions created by Envers. I was able to do that using RevisionEntity and RevisionListener but I'm not able to retrieve the data that is logged. I tried the following code

    AuditQuery auditQuery = AuditReaderFactory
            .get(factory.getCurrentSession()).createQuery()
            .forRevisionsOfEntity(Currency.class, false, false)
            .add(AuditEntity.id().eq("ENV_US"));

    List<Object[]> l = auditQuery.getResultList();

This returned a List In the object array first element is the Revision Second is of RevisionEntity and third is of RevisionType, but the values in RevisionEntity object are all null.

Here is the pojo for RevisionEntity

@Entity
@Table(name = "REVINFO")
@RevisionEntity(RevListener.class)
public class ExampleRevEntity {
@Id
@GeneratedValue
@RevisionNumber
@Column(name = "REV")
private int rev;

@RevisionTimestamp
@Column(name = "REVTSTMP")
private long revtstmp;

@Column(name = "USERID")
private String userId;

public String getUserId() {
    return userId;
}

public void setUserId(String userId) {
    this.userId = userId;
}

}

Please let me know If I'm doing any thing wrong.

Upvotes: 2

Views: 4017

Answers (3)

Mihai
Mihai

Reputation: 53

I know this is an old post, but I thought I had the same issue, and my explanation is similar in a way to @Gregory explanation from above.

In debug mode, I was able to see the null's of the fields of my @RevisionEntity annotated entity in the debug window of IntelliJ under the first level of the object. It is because this object is a Hibernate proxy actually and the "real", not null values are one level deeper inside this proxy object.

After I "evaluated the expression" in IntelliJ to inspect the content of the object, the correct values were returned:

MyCustomRevisionEntity revisionEntity = (MyCustomRevisionnEntity) ((Object[]) AuditReaderFactory
                .get(entityManager)
                .createQuery()
                .forRevisionsOfEntity(Foo.class, false, false)
                .add(AuditEntity.id().eq(1L))
                .getResultList()
                .get(3))
                [1];

Inside the MyCustomRevisionEntity object, my values were here in the target field:

((ByteBuddyInterceptor)this.$$_hibernate_interceptor).target

So I was able to just fetch them like any other regular entity, and they were not null:

revisionEntity.getTimestamp()

Upvotes: 0

Gregory
Gregory

Reputation: 96

You may need to actually use the object. Hibernate/Envers will return a lazy initialized object, and debuggers will probably not be able to see the values. Once you call the getters in code, the proper values should be populated.

Upvotes: 1

adamw
adamw

Reputation: 8636

Do you want to query the revision entity itself, or retrieve audited objects including the revision entity?

If you want to query the revision entity itself, it's a completely normal entity. Just query it as all other entities - not through an AuditQuery, but using an EntityManager or Session.

If you want to retrieve audited objects including the revision entity, then the above is correct, provided that there exist revision data for the revisions at which the object changed. Do you see data in the database corresponding to the returned revisions?

Upvotes: 0

Related Questions