Auditing entities in Spring Data MongoDB
Spring Data MongoDB 1.2.0 silently introduced new feature: support for basic auditing. Because you will not find too much about it in official reference in this post I will show what benefits does it bring, how to configure Spring for auditing and how to annotate your documents to make them auditable.Auditing let you declaratively tell Spring to store:
- date when document has been created: @CreatedDate
- date when document has been updated last time: @LastModifiedDate
- user who has created document: @CreatedBy
- user who has done most recent update: @LastModifiedBy
- current document version: @Version
Configuration
First of all Maven dependencies to latest Spring Data MongoDB and Spring Data Commons. Additionally in order to use date-related audit annotations we need to add joda-time to classpath.
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 | < dependency > < groupId >org.springframework.data</ groupId > < artifactId >spring-data-mongodb</ artifactId > < version >1.2.1.RELEASE</ version > </ dependency > < dependency > < groupId >org.springframework.data</ groupId > < artifactId >spring-data-commons</ artifactId > < version >1.5.1.RELEASE</ version > </ dependency > < dependency > < groupId >joda-time</ groupId > < artifactId >joda-time</ artifactId > < version >2.2</ version > </ dependency > |
In order to enable auditing we need to add <mongo:auditing/> to Spring configuration. Currently there is no way to configure it through Java Config.
1 2 3 4 5 6 7 8 | < mongo:auditing /> < mongo:mongo id = "mongo" /> < bean class = "org.springframework.data.mongodb.core.MongoTemplate" > < constructor-arg name = "mongo" ref = "mongo" /> < constructor-arg name = "databaseName" value = "blog-tests" /> </ bean > |
Usage
Configuration above provides us way for auditing that includes versioning and timestamps. Example document will look like:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 | @Document public class Item { @Id private String id; ... @Version private Long version; @CreatedDate private DateTime createdAt; @LastModifiedDate private DateTime lastModified; ... } |
Now you can save document using MongoTemplate or your repository and all annotated fields are automagically set.
As you have probably noticed I did not use here user related annotations @CreatedBy and @LastModifiedBy. In order to use them we need to tell Spring who is a current user.
First add user related fields to your audited class:
1 2 3 4 5 | @CreatedBy private String createdBy; @LastModifiedBy private String lastModifiedBy; |
Then create your implementation of AuditorAware that will obtain current user (probably from session or Spring Security context – depends on your application):
1 2 3 4 5 6 7 8 | public class MyAppAuditor implements AuditorAware<String> { @Override public String getCurrentAuditor() { // get your user name here return "John Doe" ; } } |
Last thing is to tell Spring Data MongoDB about this auditor aware class by little modification in Mongo configuration:
1 2 | < mongo:auditing auditor-aware-ref = "auditor" /> < bean id = "auditor" class = "pl.maciejwalkowiak.blog.MyAppAuditor" /> |
The created date is missing on update. Is there a way to keep persisting this on update?