Find the best ways to implement an audit and it’s PROS and CONS

Ganesa Vijayakumar
6 min readAug 29, 2019

DB Trigger | Hibernate Interceptor | JPA annotations | Business layer

You may guys think that the mentioned items in the title are not related to each other except Hibernate Interceptors and JPA annotations. Yes, but I am thinking that these are all various approaches for doing auditing and history in other word secretly listen in on the communication between web/desktop/mobile applications and database to get information.

Here, I am going to point out some positives and negatives of all these approaches and based on the details you can choose the best approach that will suit you.

DB Trigger:

Whenever we think about to do an audit for a web application the first option comes to our mind it that creating database triggers. A database trigger is a procedural code that is automatically executed in response to certain events on a particular table or view in a database. The trigger is mostly used for maintaining the integrity of the information on the database. For example, when a new record (representing a new worker) is added to the employee’s table, new records should also be created in the tables of the taxes, vacations, and salaries. Triggers can also be used to log historical data, for example, to keep track of employees’ previous salaries

Pros:

  • Triggers can be used as an alternative method for performing referential integrity constraints.
  • By applying triggers, business rules and events are easy to store in a database and can be used consistently even if there are future updates to the database.
  • It controls on which updates are allowed in a database.
  • When a change happens in a database a trigger can adjust the change to the entire database.
  • Triggers are used for calling stored procedures.

Cons:

  • It is easy to view table relationships, constraints, indexes, stored procedure in the database but triggers are difficult to view.
  • It is easy to forget about triggers and if there is no documentation it will be difficult to figure out for new developers for their existence. You will forget the code is there. You may think that you can’t, but you will. The next guy won’t even think to look at the triggers. The net result is that things are happening in the database that nobody knows about. And if there’s a bug in the trigger? It’s gonna take forever to find because developers forget about triggers. This is a big problem. This alone is a serious reason to stay away from putting a bunch of code in triggers
  • More like compromises, you will be placing business logic into the database layer. Not always desirable

Hibernate Interceptor:

Hibernate interceptor is one of the good sense provided on hibernate especially for auditing. The Interceptor interface provides callbacks from the session to the application, allowing the application to investigate and/or manage properties of a persistent object before it is saved, updated, deleted or loaded so here we can make it possible to use it for this is to be track auditing information.

And here’s an explanation of the single callback methods. I hope this will method and details will give you more understanding that why we considered Interceptor in audit discussion.

findDirty() — This method is being called when the flush() method is called on a Session object.

instantiate() — This method is called when a persisted class is instantiated.

isUnsaved() — This method is called when an object is passed to the saveOrUpdate() method/

onDelete() — This method is called before an object is deleted.

onFlushDirty() — This method is called when Hibernate detects that an object is dirty (i.e. have been changed) during a flush i.e. update operation.

onLoad() — This method is called before an object is initialized.

onSave() — This method is called before an object is saved.

postFlush() — This method is called after a flush has occurred and an object has been updated in memory.

preFlush() — This method is called before a flush.

Pros:

  • As I described above, it is providing various options to stop the Hibernate action and modify it before it reaches into the database.
  • Mostly it will be very useful to log the records and messages for auditing purpose but also, we can use this to do some business logic too (like executing a business task if any new record added in a particular table).
  • You don’t need to change any of your existing code, just add interceptor and update the persistence.xml
  • The onFlushDirty() provides detailed info about what changed on the particular transaction.

Cons:

  • If you are looking for the case to do audit when modifying an item of the list then it will not help since the interceptor fires for every entity bean and not in a subset.
  • If your primary key is set by the database, the id is still undefined when onSave fires

JPA annotations:

JPA also providing an ability to audit information and it’s providing annotations for it. The JPA annotated Callback methods are user-defined methods that are attached to Entity lifecycle events and are invoked automatically by JPA when these events occur. Callback methods can be embedded into the Entity class or in an external class:

And here’s a description of the single callback annotations. The annotation specifies when the callback method is invoked.

@PrePersist — before a new entity is persisted (added to the EntityManager).

@PostPersist — after storing a new entity in the database (during commit or flush).

@PostLoad — after an entity has been retrieved from the database.

@PreUpdate — when an entity is identified as modified by the EntityManager.

@PostUpdate — after updating an entity in the database (during commit or flush).

@PreRemove — when an entity is marked for removal in the EntityManager.

@PostRemove — after deleting an entity from the database (during commit or flush).

Pros:

  • JPA annotations providing the same kind of benefits which provides by Hibernate methods

Cons:

  • As hibernate is a JPA implementation as like TopLink, EclipseLink, Open JPA, and DataNucleus so we can see the same issues which I mentioned as concerns for Hibernate.

Business layer:

If we are not able met expectation with the above options then we can go to manage the information in our application business layer itself. The business layer logics are fully developed and customized by end developers and there won’t be any limitations like when we use any other third-party libraries/frameworks. anyhow, there are some pluses on minuses choosing this option too. Let’s see those below.

Pros:

  • It’s independent and changeable as per our requirement needs since all the logic built based on the project-specific only.
  • The changes and the operation will verify specific instead of running it generic for all the application processes(for example: if we use Hibernate methods or JPA annotations then those methods will be triggered on every action across the applications but this is going to be very specific and involved operations only on required flows)

Cons:

  • As mentioned above, all the required changes need to be built in the business layer itself which will extend the development duration since it’s kind of reinvent the functions which are almost provided by some third-party frameworks except the concerns which we discussed in the above sections.
  • We should think in all aspects like all the possible flow which are traveling into the new business module and make sure there won’t be any performance impact because of this new business module since it is going to be a newly invented one and also occurred all the database actions too.

Conclusion:

I explored all these details during audit implementation for my project and I was able to capture the Pros and Cons of different options which we can use for implementing audit for a project. I’ve ended my exploration with choosing the last option that implementing it in the business layer after considering all the Pros and cons mentioned above. I hope it will be useful to you too if you are also looking for options to implement auditing in your project.

Happy Coding!!!

--

--

Ganesa Vijayakumar

I am a full stack coder. I’m very much interested in solving any technical problems and learning new interesting things and then blog about it to recall myself.