We have the following entity hierarchy and a EntityListener
@Entity
@EntityListeners(value = DummyListener.class)
@Audited
public class A {
@OneToMany(cascade = CascadeType.ALL, mappedBy = "a", fetch = FetchType.LAZY, orphanRemoval = true)
@Fetch(FetchMode.SELECT)
private Set<B> bs = new LinkedHashSet<B>(0);
}
@Entity
@Audited
public class B {
@ManyToOne(fetch = FetchType.EAGER, cascade = { CascadeType.MERGE, CascadeType.PERSIST })
@JoinColumn(name = "a_id", nullable = false)
private A a;
}
public class DummyListener {
@PreUpdate
public void beforeUpdate(A entity) {
entity.set...(...);
...
B old = entity.getBs().iterator().next();
old.set...(...);
...
B b = new B();
b.setA(entity);
entity.getBs().add(b);
...
}
}
In the entity listener we would like to add new B entity to the A entity collection. But after saving A, the envers didn't create audit record for new B instance in B audit table. Every other changes has audit records except new B instance.
What do we wrong? It is possible to create new instance of B in this way?
Per JPA Spec 2.1:
The point here is that by adding a new
B
and relating it toA
means you're modifying the relationships between entities, albeit a new entityB
.So taking the following code:
If you test this with just Hibernate and no auditing, you'd notice that the new instance of
B
is not even persisted when its created within the lifecycle callback of@PreUpdate
.So if Hibernate doesn't permit such a use case, there is no way which Envers would even be capable of detecting the state changes and performing the necessary collection work units.