Reputation: 75
I would like to list the changes made when calling myrepository.save(entity)
so that I can send out an event.
I using application events in spring to notify all my services about changes to my models. Some services would like to subscribe to events like "A Task has been updated, it's status has been set to 'DONE'". But just checking if its current state is 'DONE' will not suffice. Instead, it must have been changed to 'DONE'. It might just have been a rename or something like that.
Is there a way in Spring Data JPA to save a model to the database while either detecting the changes which were saved, or keeping a reference to the before and after state?
EDIT:
What I am trying to achieve is to have a snapshot of the entity before and after update. Not to catch the events, that I can do (and already to for creates). Currently my best plan is to JSON serialize before updating the object and then doing the same after updating the object. Then I can send both of these 'snapshots' with an event. I was just hoping there would be a better way which I was missing.
Upvotes: 1
Views: 6254
Reputation: 41
there are a lot of options to use
1- extend another repository and that repo reimplements the same CRUD operation and there you can notify your services.
2- use entity Listener and a. override the @PostPersist if you want to notify after update the entity or b. @PrePersist if you want to notify before update or c. @PreUpdate if you want to notify before database operation
3- use Aspects as @selsh mentioned above.
4- in case of remote services use Messaging system which i believe is not the case here.
Upvotes: 2
Reputation: 2007
If you want to implement it using Spring, then there is an option using AOP. You can declare Aspect for you service #save method and do some auditing logging. Here is an example:
@Aspect
public class EntityAuditLogAspect {
public EntityAuditLogAspect(/*inject deps here*/) {
}
/**
* On save pointcut.
*/
@Pointcut("org.springframework.data.repository.Repository+.save(..))")
public void onSavePointcut() {
}
@Around("onSavePointcut()")
public Object onSave(ProceedingJoinPoint pjp) throws Throwable {
final Object[] args = pjp.getArgs();
final Object before = args[0];
// load current value from database
// calculate diff and store it
return pjp.proceed();
}
}
Upvotes: 1