I have implemented auditing through Sping Data JPA but now I want to be able to control the update and create timestamps with custom logic. So I want to write a custom auditing entity listener that extends the Auditingentitylistener.
I have the following generic entity class where I register the custom auditing entity listener:
@MappedSuperclass
@Audited
@EntityListeners(CustomAuditingEntityListener.class)
public class AuditableEntity extends BaseEntity {
@CreatedDate
@Column(name = "created", nullable = false)
private Date created;
@CreatedBy
@JsonIgnore
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "created_by_id", foreignKey = @ForeignKey(name = "fk_entity_created_by_id"))
private Account createdBy;
@LastModifiedDate
@Column(name = "last_updated", nullable = false)
private Date lastUpdated;
@LastModifiedBy
@JsonIgnore
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "last_updated_by_id", foreignKey = @ForeignKey(name = "fk_entity_last_updated_by_id"))
private Account lastUpdatedBy;
protected AuditableEntity() {
}
...
}
The CustomAuditingEntityListener class is defined as
@Configurable
public class CustomAuditingEntityListener extends AuditingEntityListener {
public CustomAuditingEntityListener() {
super();
}
@Override
@PrePersist
public void touchForCreate(Object target) {
if (//custom logic) {
super.touchForCreate(target);
}
}
@Override
@PreUpdate
public void touchForUpdate(Object target) {
if (//custom logic) {
super.touchForUpdate(target);
}
}
}
The custom auditing entity listener is called correctly but when the super.touchForCreate(target) or super.touchForUpdate(target) gets called the timestamps are not set because the handler in the AuditingEntityListener class is null.
This is the code of the AuditingEntityListener class:
package org.springframework.data.jpa.domain.support;
@Configurable
public class AuditingEntityListener implements ConfigurableObject {
private ObjectFactory<AuditingHandler> handler;
public AuditingEntityListener() {
JoinPoint var2 = Factory.makeJP(ajc$tjp_1, this, this);
JoinPoint var1 = Factory.makeJP(ajc$tjp_0, this, this);
if (this != null && this.getClass().isAnnotationPresent(Configurable.class) && AnnotationBeanConfigurerAspect.ajc$if$bb0((Configurable)this.getClass().getAnnotation(Configurable.class))) {
AnnotationBeanConfigurerAspect.aspectOf().ajc$before$org_springframework_beans_factory_aspectj_AbstractDependencyInjectionAspect$1$e854fa65(this);
}
if ((this == null || !this.getClass().isAnnotationPresent(Configurable.class) || !AnnotationBeanConfigurerAspect.ajc$if$bb0((Configurable)this.getClass().getAnnotation(Configurable.class))) && this != null && this.getClass().isAnnotationPresent(Configurable.class) && AbstractDependencyInjectionAspect.ajc$if$6f1(var1)) {
AnnotationBeanConfigurerAspect.aspectOf().ajc$afterReturning$org_springframework_beans_factory_aspectj_AbstractDependencyInjectionAspect$2$1ea6722c(this);
}
if (!AnnotationBeanConfigurerAspect.ajc$if$bb0((Configurable)this.getClass().getAnnotation(Configurable.class)) && AbstractDependencyInjectionAspect.ajc$if$6f1(var2)) {
AnnotationBeanConfigurerAspect.aspectOf().ajc$afterReturning$org_springframework_beans_factory_aspectj_AbstractDependencyInjectionAspect$2$1ea6722c(this);
}
}
public void setAuditingHandler(ObjectFactory<AuditingHandler> auditingHandler) {
Assert.notNull(auditingHandler, "AuditingHandler must not be null!");
this.handler = auditingHandler;
}
@PrePersist
public void touchForCreate(Object target) {
if (this.handler != null) {
((AuditingHandler)this.handler.getObject()).markCreated(target);
}
}
@PreUpdate
public void touchForUpdate(Object target) {
if (this.handler != null) {
((AuditingHandler)this.handler.getObject()).markModified(target);
}
}
static {
ajc$preClinit();
}
}
Can someone explain how I can ensure that the AuditingHandler is not null and is set like it happens for the default AuditingEntityListener class?