Spring data revision repository: not returning onetomany when using getRevisions

Viewed 1540

I have two entity's "Application" and "ApplicationDocument"

Table 1

@Entity
@Table(name = "applications")
@EntityListeners(AuditingEntityListener.class)
public class Application {

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

@Audited
private String title;

@OneToMany(mappedBy = "application")
@JsonManagedReference
@AuditJoinTable
private List<ApplicationDocument> applicationDocuments;

}

Table 2

@Entity
@Table(name = "applicationDocuments")
public class ApplicationDocument {

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id", nullable = false)
private Long id;

@ManyToOne()
@JoinColumn(name = "applicationid")
@JsonBackReference
@Audited
private Application application;

@Audited
private String file;

}

This will create two audit tables, and the data is revisioned every time after insert, update and delete. Works fine till here

But to retrieve revisions

I have a ApplicationRepository which extends springs "RevisionRepository"

So when I fetch something like applicationRepository.getRevisions({{myApplicationId}}). Then when I look at revision entities returned, the one to many relation is always returned as null.

I would expect it to return a list with whatever ApplicationDocuments existed during that revision time.

Any ideas what am I missing here

2 Answers

The problem here is in the mapping for Application.

While both entities are being audited by Envers because they contain at least one @Audited non-id attribute, the inverse side of the collection in Application is not being audited. In short, Envers ignores the attribute because @AuditJoinTable by itself doesn't trigger the attribute to be included in the audit metadata.

You need to change your Application entity so that the collection is mapped as follows

@OneToMany(mappedBy = "application")
@Audited
@AuditJoinTable
private List<ApplicationDocument> applicationDocuments;

A shortcut to remember is that if all attributes of an entity are to be audited by Envers, you can instead annotate the actual class with @Audited to minimize the verbosity if that helps and you would have avoided having this problem too :).

I am trying out spring-data-envers at the moment and I assume you have this lib on your classpath as well. So you get the EnversRevisionRepositoryImpl under the hood, which uses the Envers AuditReader API to fetch the revision information. Relations in the returned Hibernate Proxies by this API aren´t initialized, regardless of what is specified in the JPA relationship annotations. So any OneToOne, OneToMany etc. isn´t loaded even if set to eager or eager by default.

There are bugs/feature request regarding this problem e.g.

Eagerly load collections when indicated so in the annotation defining the relation

Allow specifying join fetches through the AuditQuery API

Related