How to Use Basic Auditing with Spring Data

One of the many things Spring Data offers is a basic auditing functionality. It is great if you only need to track who made changes to your model and when. So, let's stop the talking and dive into it.

Setting Up Auditing

The first thing we need to do is to enable this feature on a @Configuration class by adding a new annotation. However, the name of the annotation is different for each datastore, e.g. @EnableMongoAuditing for use with MongoDB or @EnableJpaAuditing when you work with JPA.

So, if we would turn the example from my Spring Data MongoDB tutorial to use auditing, it starts like:

@SpringBootApplication
@EnableMongoAuditing
public class SpringDataMongodbTutorialApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringDataMongodbTutorialApplication.class, args);
    }
}

Now, let's add the auditing fields to the model class, User:

@CreatedBy
private String user;

@CreatedDate
private Instant createdDate;

@LastModifiedBy
private String lastModifiedUser;

@LastModifiedDate
private Instant lastModifiedDate;

The annotations @CreatedBy, @CreatedDate, @LastModifiedBy and @LastModifiedDate are part of the auditing feature and set the exactly the value as they are named. The Date/Timestamps fields are handled transparently by Spring Data, and you can use JodaTimes DateTime, old Java Date, and Calendar or Java 8 date/time types. However, for @CreatedBy and @LastModifiedBy we need to provide the user somehow for Spring Data.

To collect this information, Spring Data provides a AuditorAware interface we need to implement and, of course, make the bean available in the Spring Context.

@Component
public class UserAudtiting implements AuditorAware<String>{

    @Override
    public Optional<String> getCurrentAuditor() {

        String uname = SecurityContextHolder.getContext().getAuthentication().getName();
        return Optional.of(uname);
    }

}

In this example, we get the currently logged in user from Spring Security. However, if you don't use that in your project, here's the place to get the changing users identity.

The type we use in our AuditorAware implementation must match the type of the field we set the @CreatedBy or @LastModifiedBy annotations on. In the example, we just store the username, but you could also use your own user or security details class...

You are also free to mix the annotations as you want; you don't need to add all four of them to a model.

Conclusion

It is straight forward to use, transparent and covers the most common use cases. Consider it next time you need an auditing feature.