8

How can i get only modified fields from audited entity?

When i use

AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(MyEntity.class, revisionNumber).getResultList()

I get all fields; but i want to get only fields modified?

GhostCat
  • 137,827
  • 25
  • 176
  • 248
Melek ELLOUZE
  • 83
  • 1
  • 1
  • 3
  • "only fields modified", in what format do you need the fields? String-array? Between revisionNumber and revisionNumber-1 or current? Please be more specific. – Grim Apr 18 '17 at 13:04
  • we suppost i have entity person id, name, birthDay if i modify name envers create revision with all fields and i want to get name has change form Melek to Melek Ellouze for exemple. – Melek ELLOUZE Apr 18 '17 at 13:23
  • Do you like to have further changes to the name changed *after* your renaming? Or only your renaming? – Grim Apr 18 '17 at 15:01
  • Only current change for the revision (only renaming) but if for the same revision i change change firstName and lastName i want get changed fields firstName from xxx to yyy LastName from xxx to yyy – Melek ELLOUZE Apr 18 '17 at 15:16

1 Answers1

8

Without Modified Flags Feature

If you are not using the Modified Flags feature on the @Audited annotation, the only way to obtain that an audited property changed from revision X to revision Y is to actually fetch both revisions and then compare the actual field values between the two object instances yourself.

With Modified Flags Feature

Assuming you are using the Modified Flags feature on the @Audited annotation, presently the only way is to fetch the revision numbers for a given entity instance and using those revisions and prior knowledge of the audited columns, use the Envers Query API to ask whether a property changed for that revision.

Obviously this approach is not ideal as it does impose some prior knowledge on the user code's part to know the fields that are audited in order to get the desired result.

List<Number> revisions = reader.getRevisions( MyEntity.class, myEntityId );
for ( Number revisionNumber : revisions ) {
  for ( String propertyName : propertyNamesToCheckList ) {
    final Long hits = reader.createQuery()
      .forRevisionsOfEntity( MyEntity.class, false, false  )
      .add( AuditEntity.id().eq( myEntityId ) )
      .add( AuditEntity.revisionNumber().eq( revisionNumber ) )
      .add( AuditEntity.propertyName( propertyName ).hasChanged() )
      .addProjection( AuditEntity.id().count() )
      .getSingleResult();

    if ( hits == 1 ) {
      // propertyName changed at revisionNumber
    }
    else {
      // propertyName didn't change at revisionNumber
    }
  }
}

Modified Flags Property Changes Queries

In Hibernate Envers 6.0, we are introducing a new query that combines forRevisionsOfEntity with the modified flags query mechanism to obtain not only the revised instances for a given entity class type and primary key, but also a list of fields that were modified at each revision.

The following pseudo code gives an example of the future API:

List results = reader.forRevisionsOfEntityWithChanges( MyEntity.class false )
   .add( AuditEntity.id().eq( entityId ) )
   .getResultList();

Object previousEntity = null;
for ( Object row : results ) {
  Object[] rowArray = (Object[]) row;
  final MyEntity entity = rowArray[0];
  final RevisionType revisionType = (RevisionType) rowArray[2];
  final Set<String> propertiesChanged = (Set<String>) rowArray[3];
  for ( String propertyName : propertiesChanged ) {
    // using the property name here you know
    // 1. that the property changed in this revision (no compare needed)
    // 2. Can get old/new values easily from previousEntity and entity
  }
}

This feature may be expanded upon or changed as it is going to be considered experimental, but it is something that users have asked for and we at least intend to deliver a first pass at this functionality based on modified flags.

We haven't decided if or how we'd support this for non-modified flags at the moment, so again the only choice there will presently be a brute force bean comparison.

Fore more details on this feature see HHH-8058.

Community
  • 1
  • 1
Naros
  • 19,928
  • 3
  • 41
  • 71