Reputation: 91
We use Spring Data with die AuditEntityListener to update the change-user and the changedate. But for our migration (Spring Batch) of old data we need to set the create-user and the change-user manualy, but we cannot disable the functionality of the AuditEntityListener. We also use envers in some entities, so I can't implement the AuditEntityListener by myself.
Do I have to copy my entity-classes?
Upvotes: 2
Views: 780
Reputation: 140
I have exactly the same problem, and this is how I ended up resolving it. I am using Spring Boot 3.2
public class CustomAuditEntityListener extends AuditingEntityListener {
public CustomAuditEntityListener(ObjectFactory<AuditingHandler> auditingHandler) {
super.setAuditingHandler(auditingHandler);
}
@PrePersist
public void customPrePersist(Object target) {
try {
Field uuidField = target.getClass().getSuperclass().getDeclaredField("createdAt");
uuidField.setAccessible(true);
Object uuidValue = uuidField.get(target);
if (uuidValue == null)
super.touchForCreate(target);
uuidField.setAccessible(false);
} catch (NoSuchFieldException | IllegalAccessException ignored) { }
}
@PreUpdate
public void customPreUpdate(Object target) {
try {
Field uuidField = target.getClass().getSuperclass().getDeclaredField("updatedAt");
uuidField.setAccessible(true);
Object uuidValue = uuidField.get(target);
if (uuidValue == null)
super.touchForUpdate(target);
uuidField.setAccessible(false);
} catch (NoSuchFieldException | IllegalAccessException ignored) { }
}
private Class<?> getClass(Object target) {
return ProxyUtils.getUserClass(target);
}
}
@MappedSuperclass
@EntityListeners(CustomAuditEntityListener.class)
@JsonIgnoreProperties(
value = {"createdAt", "updatedAt"},
allowGetters = true
)
@Setter
public abstract class DateAudit implements Serializable {
@CreatedDate
@Column(updatable = false)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "UTC")
private Instant createdAt;
@LastModifiedDate
@Column
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "UTC")
private Instant updatedAt;
public Instant getCreatedAt() {
if(this.createdAt != null)
return LocalDateTime.ofInstant(this.createdAt, ZoneOffset.UTC).toInstant(ZoneOffset.UTC);
return null;
}
public Instant getUpdatedAt() {
if(this.updatedAt != null)
return LocalDateTime.ofInstant(this.updatedAt, ZoneOffset.UTC).toInstant(ZoneOffset.UTC);
return null;
}
}
The above entity is used like so:
public class EntityIWantToHaveAudit extends DateAudit {
// properties
}
With the above configuration, when I migrate old data that already have a createdAt
and an updatedAt
they are not overwritten. For new entities the auditing works as expected.
Upvotes: 1