In this tutorial, we will discuss how to audit data and generating audit logs and data history entries using JaVers in a Spring boot and MongoDB environment.

Please note that MongoDB is a relatively young system with a lot of potential. It is also one of the most increasingly used DB systems out there. If you would like to learn more about MongoDB to prepare yourself for new and exciting career opportunities, then we recommend that you check out the book “Mastering MongoDB 4.x: Expert techniques to run high-volume and fault-tolerant database solutions using MongoDB 4.x, 2nd Edition” (click to check current price on Amazon).

Prerequistes

If you currently do not have a Spring boot environment set up with a MongoDB backend, then we suggest that you check out our Spring boot and MongoDB configuration example

This tutorial picks it up from there and extends that example so make sure you are up to date 😉

Introduction

Reasons for maintaining an audit log

In a production environment, where there are tons of data changes, an audit log, aka a data change log becomes a necessity. Reasons for maintaining an audit log include:

  • Troubleshooting purposes. For example, when an error around an entity occurs, it would be great to know which change triggered a certain bug.
  • Security purposes: Maintaining an audit log is extremely important when it comes to security. For example, checking who changed specific data sets, or finding out what was changed in order to investigate a security breach.
  • Analytics: Tracking and analyzing data changes provides you another point of view into a user’s behavior. It allows you to learn how the user interacts and changes data in order to create new functionalities and improve existing ones.
  • Data restoration: Mistakes happen. And when they do, it would be great to restore data to its original state. For example, if you make an editing mistake, then having an audit log allows you to view how data looked like before your edit and allows you to restore the data to its pre-edit state.


What is JaVers

JaVers is an open source framework that provides auditing functionality in object oriented data environments. Javers allows developers to log changes to their entities into a JaVers repository, which can later be used to perform change auditing and tracking tasks.


Why use JaVers

There are several reasons to use JaVers, including:

  • It is open source and free to use.
  • It is an actively maintained project with frequent updates and bug fixes. You can check the release notes here
  • It is compatible with both traditional relational relational database systems as well as NoSQL systems. This makes migration between RDBMS and NoSQL much smoother.
  • Easy integration with Spring and Spring Boot.


Integrating JaVers with Spring Boot and MongoDB

Integrating Javers into a Spring boot application is quite an easy task, thanks to Spring boot’s auto-configuration functionality and the existence of JaVers’ Spring boot starter module which takes advantage of the auto configuration functionality of Spring boot to get up and running very quickly.


Adding the required dependencies

In order to pull in the dependencies required to get started with JaVers in a Spring boot and MongoDB application, you will need to add the javers-spring-boot-starter-mongo dependency to your POM xml.

The dependency adds the required JaVer’s libraries and auto-configuration classes to your project. Since the auto-configuration classes are now on your classpath, Spring boot will automatically configure JaVers for you with some defaults. For the sake of simplicity of this guide, we will keep these defaults unchanged, but if you are curious, you can find more information here and here


Marking repositories for auditing

By default, JaVers will perform any auditing unless you explicitly mark your repository for auditing. To do this, you will need to use the @JaversSpringDataAuditable annotation on the repositories you would like to audit.

Remember our CarRepository from our previous tutorial ? Let us modify it with the required annotation:

By adding this annotation, you now create an audit entry for each create, update or delete operation you perform in the database.


Trying it out

Now, let us try out our brand new audit library configuration. For this, we will modify our CommandLineRunner application slightly by performing a modification and a deletion operation on our test data.

When we run our program, we will notice new log lines by our auditing framework:

This is our auditing framework persisting log data into our database. If we go to our MongoDB database, we will notice that JaVers added two new collections.

The jv_head_id collection contains only a single document with the last commitId. The jv_snapshots collection contains our data change log. Here is where all the magic can be found. For each create, update or delete operation, a document in this collection can be found. There are three types of documents that can be found:

  • Initial : This indicates a create operation in the database.
  • Update : Indicates an update / modification operation.
  • Terminate : Indicates a delete operation has been performed.

Let us check the as an example the create operation for the “488” car:

Let us highlight a few fields from our example:

  • commitMetadata: This includes valuable information such as the author of the change, the time of the event in local (commitDate) and UTC (commitDateInstant). The author here is mentioned as “unauthenticated” as we did not configure any authenticion into our spring application using spring security. We will explore this in a later tutorial.
  • globalId: Contains information about the entity being modified and its database id.
  • state: Contains all the field values of the entity being modified. Please note that this is the state of the object after the change has been performed.
  • changedProperties: This includes the fields that have been modified in this audit log entry. Since this is a creation operation, all fields have been included in the changed properties array.

Now, let us take a look at our modification operation event entry:

Notice that now, only the horsePower property has been included in the changedProperties list. Also notice that the version has been incremented to 2.

Finally, let us take a look at the deletion operation audit log entry:

Since the object has been deleted, the entry log type here is “TERMINATE”. Notice that the changed properties array is empty.


Querying the JaVers snapshots repository

Our final step here is to figure out how to access the audit logs data from our Spring boot application. For this, we simply need to obtain an instance of JaVers from the application context and search for changes for a specific car. For this, let us modify our CommandLineRunner implementation again and add a simple query to search in the JaVers snapshots collection.

For this, we will use Javers and the JaVers query builder. Make sure to import the correct classes using the following import statements:

In order to get the JaVers instance in our simple application, we simply need to autowire an instance of the bean.

Now, at the end of our run method, we will add the following code. The query will try to search for all “UPDATE” snapshots that exist for the Car entity. This can be done as follows:

If we run our program, we will get the following output:

Please note that JaVers provides a very powerful querying API. We will explore more search functionality in later tutorials.


Summary

In this tutorial, we discussed briefly what is JaVers and why it may be a good fit in a Spring boot and MongoDB stack. We then discussed how to integrate JaVers into Spring boot by adding the required dependencies and how to enable auditing for a spring repository. We then tested our example and discussed what is stored in the JaVers snapshot MongoDB collections. We then discussed a brief example for querying for JaVers entity history snapshots.

If you liked this tutorial, then please make sure to subscribe to our twitter feed by clicking on the follow button below 🙂