I need to show history of modifications on entities on UI. Something like this -
|-------------------------------------------------------------------------------------------------------------------------------------| |Entity name | Entity ID | Action by | Action on | Action Type | Old value | New value | |-------------|-------------|-------------|----------------------|---------------|--------------------------|-------------------------| |Person | 1 | John Doe | 2017-04-12 12:00:00 | Add | | name: Lily, Role: Admin | |Person | 1 | John Doe | 2017-04-15 12:00:00 | Update |name: Lily | name: Lily Smith | |Subject | 5 | Mary | 2017-04-17 12:00:00 | Update |name: Maths | name: Mathematics | |Subject | 6 | Mary | 2017-04-17 12:00:00 | Delete |name: Science, credits: 5 | | |-------------------------------------------------------------------------------------------------------------------------------------|
I used Hibernate envers to store all the data I need. But I'm having problem reading up all the data to show something like I need above. I search a lot of blogs, Questions articles, documents, javadocs on the internet, but none of them shows how to do this. All of them show how to retrieve entities based on revision or return revisions. None of these entities have following information in addition to entities returned -
- Who did the change
- When did that change happen
- What type of change was it. ADD/UPDATE/DELETE
Please note that I want as least number of queries possible to speed up the history API response.
I'm using hibernate and envers version: '5.2.9.Final'
Any help in highly appreciated.
Thank you!
Update
Here's the code -
Annotations above each entity class-
@Audited(withModifiedFlag = true)
Custom revision listener -
public class CustomRevisionListener implements RevisionListener { private static final Logger logger = LogManager.getLogger(CustomRevisionListener.class); public void newRevision(Object revisionEntity) { logger.info("newRevision, starts revisionEntity="+revisionEntity); CustomRevisionEntity revision = (CustomRevisionEntity) revisionEntity; String name = "unknown"; try{ //user custom userdetails.User to store id and name both? //or just store id in string format here? org.springframework.security.core.userdetails.User springUser = (org.springframework.security.core.userdetails.User) SecurityContextHolder .getContext().getAuthentication().getPrincipal(); name = springUser.getUsername(); //get logged in username }catch(Exception e){ logger.error("error getting username", e); } logger.info("newRevision, name="+name); User user = new User(); user.setName(name); revision.setUser(user); //for testing logger.info("newRevision, setting userId="+user.getId()); } }
Custom revision entity -
@Entity @Table(name="REVISIONS") @RevisionEntity(CustomRevisionListener.class) public class CustomRevisionEntity extends DefaultRevisionEntity { private static final long serialVersionUID = -6113123831136684807L; @ManyToOne @JoinColumn(name="USER_ID") private User user; public User getUser() { return user; } public void setUser(User user) { this.user = user; } }
envers config -
org.hibernate.envers.track_entities_changed_in_revision=true org.hibernate.envers.global_with_modified_flag=true org.hibernate.envers.store_data_at_delete=true org.hibernate.envers.audit_strategy=org.hibernate.envers.strategy.ValidityAuditStrategy org.hibernate.envers.audit_strategy_validity_store_revend_timestamp=true
Reading audits -
public List getAllAudits() { logger.debug("getAllAudits starts"); //HERE IS WHERE I NEED HELP. //below code is just for trials. I need something which will read all audits and relevant info I described above ArrayList list = (ArrayList) AuditReaderFactory.get(entityManager) .createQuery() .forRevisionsOfEntity(Organization.class, true, true) // .add(AuditEntity.id().eq(bitacoraControlId)) .addOrder(AuditEntity.revisionNumber().asc()) .getResultList(); for(int i=0; i revisions = reader.getRevisions(Organization.class, 2); for(Number revNum:revisions){ Organization article =reader.find(Organization.class, 2, revNum); System.out.println("Revision No: " + revNum); System.out.println("Title: " + article.getId()); System.out.println("Content: " + article.getName()); } logger.debug("getAllAudits list size="+list.size()); return list; }