Description
I have a problem when using custom entities, in spring data envers 2.5.3
When Create a new DefaultRevisionMetadata or AnnotationRevisionMetadata, metadata is HibernateProxy
EnversRevisionRepositoryImpl
RevisionMetadata<?> createRevisionMetadata() {
return metadata instanceof DefaultRevisionEntity //
? new DefaultRevisionMetadata((DefaultRevisionEntity) metadata, revisionType) //
: new AnnotationRevisionMetadata<>(metadata, RevisionNumber.class, RevisionTimestamp.class, revisionType);
}
DefaultRevisionMetadata
public final class DefaultRevisionMetadata implements RevisionMetadata<Integer> {
public Optional<Integer> getRevisionNumber() {
return Optional.of(entity.getId());
}
}
AnnotationRevisionMetadata
public class AnnotationRevisionMetadata<N extends Number & Comparable<N>> implements RevisionMetadata<N> {
private final Lazy<Optional<N>> revisionNumber;
public AnnotationRevisionMetadata(Object entity, Class<? extends Annotation> revisionNumberAnnotation,
Class<? extends Annotation> revisionTimeStampAnnotation, RevisionType revisionType) {
Assert.notNull(entity, "Entity must not be null!");
Assert.notNull(revisionNumberAnnotation, "Revision number annotation must not be null!");
Assert.notNull(revisionTimeStampAnnotation, "Revision time stamp annotation must not be null!");
Assert.notNull(revisionType, "Revision Type must not be null!");
this.entity = entity;
this.revisionNumber = detectAnnotation(entity, revisionNumberAnnotation);
this.revisionDate = detectAnnotation(entity, revisionTimeStampAnnotation);
this.revisionType = revisionType;
}
public Optional<N> getRevisionNumber() {
return revisionNumber.get();
}
private static <T> Lazy<Optional<T>> detectAnnotation(Object entity, Class<? extends Annotation> annotationType) {
return Lazy.of(() -> {
AnnotationDetectionFieldCallback callback = new AnnotationDetectionFieldCallback(annotationType);
ReflectionUtils.doWithFields(entity.getClass(), callback);
return Optional.ofNullable(callback.getValue(entity));
});
}
}
AnnotationDetectionFieldCallback
public class AnnotationDetectionFieldCallback implements FieldCallback {
public <T> T getValue(Object source) {
Assert.notNull(source, "Source object must not be null!");
Field field = this.field;
if (field == null) {
return null;
}
return (T) ReflectionUtils.getField(field, source);
}
}
DefaultRevisionMetadata calls Optional.of(entity.getId());
-> entity is HibernateProxy
-> HibernateProxy.getId();
AnnotationRevisionMetadata calls revisionNumber.get();
-> Optional.ofNullable(callback.getValue(entity))
-> ReflectionUtils.getField(field, source), @RevisionNumber annotated field value
Therefore, when using Custom RevisionEntity, the field value of the HibernateProxy
in org.springframework.data.history.Revision is null. Information about metadata is output only as null or Optional.empty.
if in custom RevisionEntity Adding @Proxy(lazy = false)
causes n+1 issues similar issue
any way to solve this problem?