Reputation: 5557
I've dynamoDB database, in which I've a table named user
. I want to log auditing (CreatedBy
, LastModifiedBy
, CreatedDate
, LastModifiedDate
)in this table.
I've found JPA auditing (from here) and MongoDB auditing with annotations @EnableJpaAuditing
and @EnableMongoAuditing
respectively. But obviously they are not working with dynamoDB.
Here is my abstract class for auditing:
@DynamoDBDocument
public abstract class PQSSAbstractAuditingEntity implements Serializable{
@CreatedBy
@JsonIgnore
@DynamoDBAttribute
private String createdBy;
@LastModifiedBy
@JsonIgnore
@DynamoDBAttribute
private String lastModifiedBy;
@CreatedDate
@JsonIgnore
@DynamoDBAttribute
private Date createdDate;
@LastModifiedDate
@JsonIgnore
@DynamoDBAttribute
private Date lastModifiedDate = new Date();
public String getCreatedBy() {
return createdBy;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
public String getLastModifiedBy() {
return lastModifiedBy;
}
public void setLastModifiedBy(String lastModifiedBy) {
this.lastModifiedBy = lastModifiedBy;
}
public Date getCreatedDate() {
return createdDate;
}
public void setCreatedDate(Date createdDate) {
this.createdDate = createdDate;
}
public Date getLastModifiedDate() {
return lastModifiedDate;
}
public void setLastModifiedDate(Date lastModifiedDate) {
this.lastModifiedDate = lastModifiedDate;
}
}
I've assigned dates to respective fields but I've to set createdBy
and lastModifiedBy
depending on the logged in user. So I've to fetch the dynamically at runtime, when ever new entry is added into the database.
I know how to set these fields statically but the problem is how to make annotations aware of these changes at run time.
As I mentioned, I've found AuditAware
for JPA and mongo. I need the same for dynamoDB.
Any help will be appreciated. As I'm new to Spring boot.
Upvotes: 2
Views: 3514
Reputation: 161
The question is already some years old but if somebody has also that problem, following solution works..
The problem is, that @EnableDynamoDBAuditing
and @EnableDynamoDBRepositories
don't work properly together. To solve this problem you have to add both annotations to you configuration class, create AuditorAware
and DateTimeProvider
beans and add all your entities/documents to your DynamoDBMappingContext
manually.
PersistenceConfiguration.java
@Configuration
@EnableDynamoDBAuditing(auditorAwareRef = "userAuditing", dateTimeProviderRef = "dateAuditing")
@EnableDynamoDBRepositories(basePackages = "your.repository.package.name")
public class PersistenceConfiguration {
@Bean
public AuditorAware<String> userAuditing() {
return () -> Optional.of("TestUser"); //get username from SecurityContext
}
@Bean
public DateTimeProvider dateAuditing() {
return CurrentDateTimeProvider.INSTANCE;
}
@Bean
public DynamoDBMappingContext dynamoDBMappingContext() {
DynamoDBMappingContext mappingContext = new DynamoDBMappingContext();
//add your 'entities' manually
mappingContext.getPersistentEntity(YourEntity.class);
return mappingContext;
}
// do further configuration stuff...
}
YourEntity.java
@DynamoDBTable(tableName = "YourEntity")
public class YourEntity {
@CreatedDate
@DynamoDBAttribute
@DynamoDBTypeConverted(converter = LocalDateTimeConverter.class)
private LocalDateTime createdOn;
@CreatedBy
@DynamoDBAttribute
private String createdBy;
@LastModifiedDate
@DynamoDBAttribute
@DynamoDBTypeConverted(converter = LocalDateTimeConverter.class)
private LocalDateTime updatedOn;
@LastModifiedBy
@DynamoDBAttribute
private String updatedBy;
// add further properties...
}
I know that there are some other solutions like @DynamoDBAutoGeneratedTimestamp
and the usage of their strategies, but in my mind that's the cleanest solution regarding the use of spring.
Upvotes: 4
Reputation: 39186
The annotaion @DynamoDBAutoGeneratedTimestamp
can be used along with DynamoDBAutoGenerateStrategy
to audit the item.
Strategy CREATE (Use this for Create audit):-
@DynamoDBAutoGeneratedTimestamp(strategy=DynamoDBAutoGenerateStrategy.CREATE)
public Date getCreatedDate() { return createdDate; }
public void setCreatedDate(Date createdDate) { this.createdDate = createdDate; }
Strategy ALWAYS (Use this if you want last modified date):-
@DynamoDBAutoGeneratedTimestamp(strategy=DynamoDBAutoGenerateStrategy.ALWAYS)
public Date getLastUpdatedDate() { return lastUpdatedDate; }
public void setLastUpdatedDate(Date lastUpdatedDate) { this.lastUpdatedDate = lastUpdatedDate; }
If you want both create timestamp and last modified timestamps, please create two different attributes. One attribute should use CREATE strategy and other one should use ALWAYS strategy.
Upvotes: 2