Canlla
Canlla

Reputation: 249

Envers - MappedSuperclass attribute not found. @AuditMappedBy points to a property that doesn't exist

I am trying to add envers into my project but I have problems with the visibility of a MappedSuperclass attribute. The structure is like this:

A parent abstract class

@MappedSuperclass
abstract class Parent {

  @ManyToOne
  @JoinColumn(name = "joinedEntity_id")
  protected JoinedEntity field;
}

Two child classes that extend the parent class with @Audited annotation and @AuditOverride, both have the same structure:

@Audited
@AuditOverride(forClass = Parent.class, isAudited = true)
class Child extends Parent {

   Child{ super(...); }
}

And the joined entity like this:

public class JoinedEntity {

  @Singular
  @OneToMany(mappedBy = "field", cascade = CascadeType.ALL, orphanRemoval=true)
  @LazyCollection(LazyCollectionOption.FALSE)
  @AuditMappedBy(mappedBy = "field")
  private List<Child> childs;
}

And the error comes because from the JoinedEntity class it can't get resolve the AuditMappedBy that points to the abstract class attribute, even though I add the AuditOverride in the child class. Here is the error:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.MappingException: @AuditMappedBy points to a property that doesn't exist: $path.Child.field

Upvotes: 1

Views: 2567

Answers (1)

Naros
Naros

Reputation: 21163

I suspect it is because you're using @AuditMappedBy to point a non-audited property.

If you take a look at your definition of Child, the @AuditOverride specifically states that for all properties that are declared in Parent, they are not audited. So you have 3 options here.

  1. Define the field property in the Parent class as being audited, whether you do that via the @AuditOverride annotation or specifically adding the @Audited annotation to the property in the Parent class should work.

  2. Define the association in the JoinedEntity as the relation not being audited. In other words, this causes the FK value to be audited but the relationship between them are not. This means when you fetch revisions of JoinedEntity, the association is always loaded from the ORM main table.

    @Audited(targetAuditMode = RelationTargetMode.NOT_AUDITED)
    @AuditMappedBy(mappedBy = "field")
    
  3. Remove the @AuditMappedBy since the Parent class field property is not audited.

Upvotes: 1

Related Questions