Envers inserts erroneous audit entries for many-to-many relation if using `global_with_modified_flag`
Description
Activity
Show:

Chris Cranford August 10, 2022 at 5:22 PM
As explained on Zulip, the issue in this situation is the use of getReference()
versus find()
.
In order for Envers to perform proper diff analysis on entity state, the entity must be loaded fully into the PersistenceContext. When using getReference()
, the entity’s full state isn’t loaded by ORM and therefore only the primary key fields are available. Envers also does not lazily load this state because this can create other cascading concerns during the listener invocation. So we ultimately rely on the user to guarantee the entity’s state is loaded so the right audit state gets persisted.
You can workaround and avoid this by using EntityManager#find()
rather than EntityManager#getReference()
.
If using the config option
global_with_modified_flag
, envers creates erronous audit entries for ManyToMany relations in certain cases.Suppose EntityA and EntityB are related via a ManyToMany relation and EntityA is the owning side of the relation. In this case I can remove an EntityB from the relation, persist the EntityA and the relation is updated correctly. If envers is configured with `
global_with_modified_flag
, it creates 3 audit entries, one for the relation, one for the owning and one for the owned side. The audit entry for the owned side does not contain any data except forid
,rev
,revtype
and the*_mod
fields. The_mod
field that corresponds to the relation is set to true like it is expected. All other fields arenull
.I would expect that all other fields are filled with the current values.
I wrote a reproducer for this problem, the last assert fails:
If anyone can help me with a workaround for this, I would be very thankful.