How to track delete events with Spring Data JPA auditing and Envers? [duplicate]
Asked Answered
P

2

9

In my audited entity I have last modified fields:

@LastModifiedBy
private String lastModifiedBy;

@LastModifiedDate
private OffsetDateTime lastModifiedDate;

But they doesn't change when entity is deleted.

As I understand, I need to customize org.springframework.data.jpa.domain.support.AuditingEntityListener and add @PreRemove there, but I don't understand how to implement this, because I always get the following error:

org.hibernate.InstantiationException: Could not instantiate managed bean directly

Is there any other options to track delete events and store updated fields to Envers audit table?

Platinumblond answered 27/11, 2019 at 13:51 Comment(2)
Those annotations are spring-data-envers specific I do believe so hopefully someone from that community can provide a more flushed answer; however strictly from Envers perspective all we store is the current entity-state prior to removal. I believe the suggestion with @PreRemove is to alter that current entity-state in memory prior to the event listeners for auditing. That said, Envers does not store non-primary key attributes by default for deleted rows. There is a configuration option, org.hibernate.envers.store_data_at_delete which needs to be set to true to accomplish this.Gascony
@Gascony i've posted my workaround, what do you think about it ?Platinumblond
P
5

I made this workaround:

public class CustomValidityAuditStrategy extends ValidityAuditStrategy {

    private final AuditorAware<String> auditorAware = ...;

    @Override
    public void perform(final Session session, final String entityName,
                        final AuditEntitiesConfiguration audEntitiesCfg,
                        final Serializable id, final Object data,
                        final Object revision) {
        if (data instanceof Map) {
            final Map dataToUpdate = (Map) data;
            dataToUpdate.put("lastModifiedBy", auditorAware.get());
            dataToUpdate.put("lastModifiedDate", OffsetDateTime.now());
        }
        super.perform(session, entityName, audEntitiesCfg, id, data, revision);
    }
}
Platinumblond answered 27/11, 2019 at 15:34 Comment(1)
I believe you will want to only perform this if and only if the operation is a DELETE. As of now, this will modify the values of those two attributes regardless of which DML operation you perform, insert, update, or delete. I think it would probably be better to implement a custom PreDeleteEventListener where you take the entity state and manipulate it. This way you guarantee this runs only on delete operations.Gascony
W
0

Spring Data JPA auditing by itself doesn't capture delete events. Envers, however, can track entity deletions. Here's how to address this with and without customizing the AuditingEntityListener:

  1. Add a boolean flag named deleted (or similar) to your entity.
  2. Update your delete logic to set this flag to true instead of physically deleting the entity.
  3. Configure Envers to audit this deleted flag.

This approach allows Envers to track the deletion event and store the entity state before the flag was set.

Woo answered 6/3 at 19:37 Comment(1)
I would probably only do this if I actually wanted soft deletes for that particular record anyway.Regenerative

© 2022 - 2024 — McMap. All rights reserved.