Envers ManyToMany Query

Hi,

I am trying to perform an envers audit query on a many-many relationship. Simplified, my entity mappings looks like the following:

public class Party {

    @Audited
    @AuditMappedBy(mappedBy = "parties")
    @ManyToMany(mappedBy = "parties")
    private List<Contact> contacts = new ArrayList<>();
}
public class Contact {

    @Audited
    @JoinTable(name = "contact_party", <...mappings...>))
    private List<Party> parties = new ArrayList<>();
}

I would like to query for audits of Contact, where ‘parties’ contain a given Party. Unfortunately, I receive the error: This type of relation (…package…Contact.parties) can’t be used in audit query restrictions.

My query code resembles the following:

AuditReaderFactory
    .get(entityManager)
    .createQuery()
    .forRevisionsOfEntityWithChanges(Contact.class, true)
    .add(AuditEntity.property("parties").eq(party)));

I have seen tickets in relation to this (Jira) and I am running hibernate envers version 6.6.4. The code builds as expected and audit DB entries are created correctly - I just can’t figure out a way to query them

Are there plans to support queries of this type? Or, is there a way to query the many-many relationship that I am missing?

Does something like work for you?

AuditReaderFactory
    .get(entityManager)
    .createQuery()
    .forRevisionsOfEntityWithChanges(Contact.class, true)
    .traverseRelation( "parties", JoinType.INNER, "party" )
    .add(AuditEntity.property("id").eq(party.getId()));

Hi Beikov,

Unfortunately not, you get the error: Audit association queries are only permitted when the query is created with selectEntitiesOnly=true

Which I do try:

AuditReaderFactory
    .get(entityManager)
    .createQuery()
    .forRevisionsOfEntity(Contact.class, true, true)
    .traverseRelation("parties", JoinType.INNER, "party")
    .add(AuditEntity.property("id").eq(party.getId()))
    .getResultList();

But it gives a further error: QueryParameterException: No argument for named parameter ‘:revision’

org.hibernate.query.internal.QueryParameterBindingsImpl.validate(QueryParameterBindingsImpl.java:182)
org.hibernate.query.spi.AbstractSelectionQuery.beforeQuery(AbstractSelectionQuery.java:166)
org.hibernate.query.spi.AbstractSelectionQuery.beforeQueryHandlingFetchProfiles(AbstractSelectionQuery.java:159)
...

Querying for a specific revision doesn’t give an error, but at that point I will have negated the purpose of the original code, which is to find all ‘Contact’ audits in a ‘Party’ :slightly_frowning_face:

Ideeally we would have it working via ‘forRevisionsOfEntityWithChanges’. Does it sounds like a bug?

I don’t know for sure, but to me this looks like a bug, yes. I am no expert on Envers though, so maybe the answer might be “this is not supported yet”.

Since Envers uses HQL behind the scenes though, you should be able to formulate whatever query you want by hand.

Also see other answers I gave that discuss this topic:

1 Like