I am using Spring Mongo Auditing and @CreatedDate @CreatedBy not working but @LastModifiedDate and @LastModifiedBy working fine.
I added @EnableMongoAuditing on a configuration class and also defined the AuditAware.
@Component("securityAuditorAware")
public class SecurityAuditorAware implements AuditorAware<String> {
@Override
public Optional<String> getCurrentAuditor() {
return Optional.ofNullable(SecurityUtils.getUserPrincipal()).map(AuthenticatedUser::getIssuer);
}
}
Auditing class is:
@Document
public class Template {
@Id
private UUID id = UUID.randomUUID();
@CreatedDate
private Date createdOn;
@LastModifiedDate
private Date modifiedOn;
@CreatedBy
private String createdBy;
@LastModifiedBy
private String modifiedBy;
}
When I save the document it put null in both createdOn and createdBy but the right values in both modifiedOn and modifiedBy
Thanks for the help
If your Entity does not inheritance Persistable
interface, you should define a field which marked by @Version
(org.springframework.data.annotation.Version).
@Document
public class Template {
@Id
private UUID id = UUID.randomUUID();
@CreatedDate
private Date createdOn;
@LastModifiedDate
private Date modifiedOn;
@CreatedBy
private String createdBy;
@LastModifiedBy
private String modifiedBy;
@Version
private Integer version;
}
In other side, if your entity inheritance Persistable
interface, you should implement logical which to detect the entity never been persisted before.
For more information, you can check two class: PersistentEntityIsNewStrategy
and PersistableIsNewStrategy
I had similar issue recently, and I did a bit of digging around to see how auditing actually works, so I am just putting it here in case any one else runs into the same problem.
First of all, here are relevant spring docs regarding auditing with regards to mongo:
So auditing works via EntityCallbacks
(defined in the spring-data-commons
project) and the specific callback(s) that we need to run for mongo is either the AuditingEntityCallback
or the ReactiveAuditingEntityCallback
both defined in the spring-data-mongodb
project.
Please note that all that these EntityCallback
(s) does is to give either the AuditingHandler
or ReactiveAuditingHandler
in the spring-data-commons
project a change to do their work, both of these classes extends the AuditingHandlerSupport
abstract class and I would recommend putting a break point on the isAuditable
method:
/**
* Returns whether the given source is considered to be auditable in the first place.
*
* @param source must not be {@literal null}.
* @return {@literal true} if the given {@literal source} considered to be auditable.
*/
protected final boolean isAuditable(Object source) {
Assert.notNull(source, "Source entity must not be null");
return factory.getBeanWrapperFor(source).isPresent();
}
Please note that the method above uses the property factory
which is of type AuditingHandlerSupport
to get bean wrapper, and ultimatly decide if the object can be audited or not, so you are definitly going to want to step into that if you are running a debugger. There is only one class that extends it, the DefaultAuditableBeanWrapperFactory
and then there is a class that extends that one in turn, the MappingAuditableBeanWrapperFactory
. Both define the getBeanWrapperFor
method, so if you are going to put breakpoints on this level add it to both classes.
Just out of interest I put my breakpoint in the DefaultAuditableBeanWrapperFactory.getBeanWrapperFor
method and was quickly able to resolve my mistake:
/**
* Returns an {@link AuditableBeanWrapper} if the given object is capable of being equipped with auditing information.
*
* @param source the auditing candidate.
* @return
*/
@Override
@SuppressWarnings("unchecked")
public <T> Optional<AuditableBeanWrapper<T>> getBeanWrapperFor(T source) {
Assert.notNull(source, "Source must not be null");
return Optional.of(source).map(it -> {
if (it instanceof Auditable) {
return (AuditableBeanWrapper<T>) new AuditableInterfaceBeanWrapper(conversionService, (Auditable<Object, ?, TemporalAccessor>) it);
}
AnnotationAuditingMetadata metadata = AnnotationAuditingMetadata.getMetadata(it.getClass());
if (metadata.isAuditable()) {
return new ReflectionAuditingBeanWrapper<T>(conversionService, it);
}
return null;
});
}
So I am on Spring Boot 2.7.3 which uses spring data commons 2.7.2 and spring data mongodb 3.4.2, and to fix my issue, (I use both blocking and reactive repositories), I had to add both two annotations to my data configuration:
/**
** NOTE @EnableMongoAuditing for blocking access
** NOTE @EnableReactiveMongoAuditing for reactive access
**/
@Configuration
@EnableMongoAuditing
@EnableReactiveMongoAuditing
public class MyProjectDataConfig
{
// ...
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.