Base model with @Audited

11k views Asked by At

I use @Audited annotation for my base model. I extend that for all my entities. but it not work. Is there any method I can use that

this is my base model

@MappedSuperclass
@Getter
@Setter
@Audited 
public abstract class BaseModelObject implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 4194525198831057382L;


    @Id     
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    protected Long id;
}

This is my model class

@Entity
public class City extends BaseModelObject {

    private static final long serialVersionUID = 1L;

    @Column
    private String name;
 }
2

There are 2 answers

2
Naros On BEST ANSWER

The @Audited annotation doesn't work the way you believe it should. By using it on a super class, it has no impact to the child classes which extend it, at least to control whether the child is or is not audited. This is by design.

Consider the notion where we have a superclass type and two different implementations, one which we want to audit with its superclass properties and one which we don't.

@MappedSuperclass
@Audited
public class Animal {}

@Entity
@Audited
public class Cat extends Animal {}

@Entity
public class Dog extends Animal {}

In this example, since @Audited isn't inherited, merely placing the annotation on the superclass and the Cat entity result in just Cat being audited. The Dog entity and its superclass property values are not.

If @Audited were treated as an inherited annotation, we'd have to introduce a series of @AuditOverride annotations to accomplish the same example, see below.

@MappedSuperclass
public class Animal {}

@Entity
@Audited
@AuditOverride(...)
public class Cat extends Animal {}

@Entity
public class Dog extends Animal {}

What makes this worse is if Animal had a subset of its properties audited, which would influence the number of @AuditOverrides.

This becomes even more complicated when you start to look at entity inheritance strategies and how those come into play with whether to audit an entity or not, and to what degree at what level of the hierarchy.

There is an entire discussion HHH-6331 and HHH-9770.

In short, if you want your child classes audited, they'll need to be explicitly annotated.

1
David Pérez Cabrera On

Try with this:

Superclass:

@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class AuditableEntity implements Serializable {

    private static final long serialVersionUID = 1L;

    @CreatedDate
    private LocalDateTime createdDate;

    @LastModifiedDate
    private LocalDateTime lastModifiedDate;

    @CreatedBy
    private String createdBy;

    @LastModifiedBy
    private String lastModifiedBy;

    ...
 }

Entity class:

@Entity
public class City extends AuditableEntity {

    @Id

    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    ...
}

Configuration:

@EnableJpaAuditing
@SpringBootApplication
@EnableTransactionManagement
@EntityScan("foo.entities")
@ComponentScan("foo")
@EnableJpaRepositories("foo.repositories")
public class ConfigApp {

    ...
}

Auditor service:

@Service
public class AuditorServiceImpl implements AuditorAware<String> {

    @Override
    public String getCurrentAuditor() {
        return SecurityContextHolder.getContext().getAuthentication().getName();
    }
}