Hibernate Envers - Audit Logging Made Easy
One of the requirements for my most recent project was to provide a detailed audit trail for any changes made to my database entities through the administration panel. I needed to keep track of what was changed (at a field level) and who made the change. There are a ton of ways to do this, including triggers, plain old system logging, and homebrew audit tables. But, I decided to look around for something cooler than that. Enter Hibernate Envers. What’s nice about it is configuration is basically a one-liner (for the most part), and it plays nice with my existing all-annotations JPA2 Spring MVC project. All you need to do is mark your entities with the @Audited annotation, and it takes care of the rest for you. Here’s an example:
Maven dependency (pom.xml):
Entity:
And, that’s it! So what does this do? Let’s look at the tables that Hibernate will generate:
Basically, with the default configuration, you end up with another table with the same name as your existing table but with “_AUD” appended on the end. You can also change the generated name of the tables if you want. It has the same fields as your entity table but adds a REV number to keep track of the revision, and a REVTYPE to indicate an addition, modification, or delete. Read more about this in the documentation. Each time any field is changed on one of your entities an entry will be written to this table saving the state, which allows you to easily see what changed between 2 revisions. Envers also includes utilities to query over these tables to find all the revisions for a certain entity.
Generating Schema DDL
By the way, if you are looking for an easy way to generate the DDL for your entities AND your envers tables, here’s some code. I had trouble finding a Maven plugin that supported BOTH Hibernate 4 and Envers, so this is what I did:
Summary
So yeah, Hibernate Envers is an awesome time-saver if you need an audit trail. Keep in mind that these tables can grow quickly in size if you have a lot of changes to your entities happening regularly. But otherwise, I’m really glad I found this since it was just what I needed. Enjoy!