Hi all,
We are using envers for most of our entites.
We have immutable entities that are not audited to avoid duplicated data in out DB (it’s big tables).
When we have a transaction that both updates audited entities and creates immutable ones, only the audited are recorded in the revchanges table.
It would be nice to have also the immutable entities recorded in revchanges.
With this we can retrieve the list of all the changes.
Is there a strategy / solution to achieve it ?
Is there an issue to add rows to rechanges for unaudited entities ?
What do you think to add a PersistEventListener to create these rows ?
Hello @Philippe_Kernevez, as you assumed it is not possible at the moment to support non-audited entities in the audited/envers specific REVCHANGES tracking table.
Is there an issue to add rows to rechanges for unaudited entities ?
Not that I could find, but feel free to open one. Note that, while hibernate-envers is still supported, we probably won’t be adding new features going forward - but we can still evaluate whether this functionality can be added to the new hibernate core @Audited entities.
What do you think to add a PersistEventListener to create these rows ?
Manually adding records to the REVCHANGES table is probably not a good idea, as it might probably cause errors with the Envers-native APIs relying on that table which assume only @Audited entities can live there. You can give it a try and let us know if anything breaks, it might be useful information to (eventually) add first class support for this.
Hi @mbladel,
I have an implementation that works even if I didn’t try to call all the envers APIs with the new lines in REVCHANGES.
We now have entities annotated with a custom @AuditedImmutable marker.
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface AuditedImmutable {
}
And its usage:
@Entity
@AuditedImmutable
@Table(name = "MOVEMENT")
public class MovementEntity extends ImmutableAbstractEntity<IdTypes> {
We hook an immutable listener on @PrePersist on a JPA EntityListener. From there we grab the current revision via Envers:
class ImmutableTrackingEntityListener {
@PrePersist
public void prePersist(Object entity) {
// ...filter out non-immutable entities...
SessionImplementor session = em.unwrap(Session.class).unwrap(SessionImplementor.class);
EnversService envers = session.getSessionFactory()
.getServiceRegistry()
.requireService(EnversService.class);
AuditProcess ap = envers.getAuditProcessManager().get(session);
RevisionEntity rev = (RevisionEntity) ap.getCurrentRevisionData(session, /* persist */ true);
// attach a child entity (cascade=PERSIST) to rev.modifiedEntities
new CustomRevisionTrackedEntity(entity.getClass().getName(), abstractEntity.getId(), rev);
}
}
Our ImmutableAbstractEntity register the listener:
@EntityListeners({ImmutableTrackingEntityListener.class})
With this we now have new lines for each immutable entity created and we can retrieve all the changes.
I think it would be nice to have a such mechanism natively supported.
What is the Envers merge in core ? Is something plan for v7 or work in progress for v8 ?
Regards,
Philippe
With this we now have new lines for each immutable entity created and we can retrieve all the changes.
Yes, of course you can always manipulate the REVCHANGES table manually through e.g. the listeners you implemented. But whenever you might try to use the Envers APIs to read from that table, we have several checks in place that only @Audited entities can be included - so you will probably either see errors at read-time, or have to use your own custom query logic for the read side.
What is the Envers merge in core ? Is something plan for v7 or work in progress for v8 ?