Reputation: 11
Is it posible to capture the entity (Book) that is being modified inside a CustomEntityTrackingListener or a CustomRevisionListener ?
Im trying to get all the information that is being passed through the apis /saveBook or /update/{id}/{pages}, not just the revision information.
When auditing an Entity in envers, it creates automatically a _AUD table for each entity and a revision table to connect the entity and its _AUD table
Using a custom revision listener I can get only the info about the revision, but I would like to reach the entity itself is being modified and saved.
...
@PostMapping("/saveBook")
public Book saveBook(@RequestBody Book book) {
return repository.save(book);
}
@PutMapping("/update/{id}/{pages}")
public Book updateBook(@PathVariable int id, @PathVariable int pages) {
Book book = repository.findById(id).get();
book.setPages(pages);
return repository.save(book);
}
...
@Entity
@AllArgsConstructor
@NoArgsConstructor
@Data
@Audited
public class Book {
@Id
@GeneratedValue
private int id;
private String name;
private int pages;
}
@Entity
//@RevisionEntity(ExampleListener.class)
@RevisionEntity(CustomEntityTrackingRevisionListener.class)
public class ExampleRevEntity extends DefaultRevisionEntity {
private String username;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@OneToMany(mappedBy="revision", cascade={CascadeType.PERSIST, CascadeType.REMOVE})
private Set<ModifiedEntityTypeEntity> modifiedEntityTypes =
new HashSet<ModifiedEntityTypeEntity>();
}
public class ExampleListener implements RevisionListener {
@Override
public void newRevision(Object revisionEntity) {
ExampleRevEntity exampleRevEntity = (ExampleRevEntity) revisionEntity;
//Identity identity = (Identity) Component.getInstance("org.jboss.seam.security.identity");
exampleRevEntity.setUsername("Joaquin");
}
}
public class CustomEntityTrackingRevisionListener implements EntityTrackingRevisionListener {
@Override
public void entityChanged(Class entityClass, String entityName,
Serializable entityId, RevisionType revisionType,
Object revisionEntity) {
String type = entityClass.getName();
//((CustomTrackingRevisionEntity)revisionEntity).addModifiedEntityType(type);
((ExampleRevEntity)revisionEntity).addModifiedEntityType(type);
}
@Override
public void newRevision(Object revisionEntity) {
}
}
Upvotes: 1
Views: 1531
Reputation: 129
EntityTrackingRevisionListener.entityChanged()
is executed after the object persistence, so you can get it from persistence context via find()
method of your EntityManager
using the identifier and entity class provided.
Upvotes: 1
Reputation: 21103
There are a couple ways you can accomplish this.
In the first approach, you would likely want to follow the suggestions in the Envers documentation about how you would do conditional auditing and introduce custom event listeners that extend the Envers listeners in order to deduce the changes and perform whatever tasks you need.
This can be a very daunting and tedious step because you have to understand both how Hibernate emits its data in the events, how to resolve differences, etc.
I believe the easier approach here would be to use a tool such as Debezium that enables you to setup a job that monitors a configured number of tables, in your use case the specific _AUD
tables of interest. Every time Envers inserts into those tables, Debezium would react to the insert by generating an event that you can then react against asynchronously.
Debezium has several ways of being used including being embedded into an application which might be suitable for your use case or in a Kafka Connect instance that is separate from the application and provides redundancy and fault tolerance for event capture and dispatch.
Upvotes: 0