Skip to content

Custom RevisionEntity class Metadata null #313

Closed
@csh0034

Description

@csh0034

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?

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions