Description:
|
I've discovered this issue while trying to write a query for finding all deleted instances of an entity class, along with the last non-delete revision so I can give users an idea about what exactly was deleted. Since Envers doesn't currently support joins, I need to do this query in two steps: first find all revisions that have a DEL type, then do a second query to get the latest non-DEL revision of all entities returned by the first query. I'm trying to accomplish the second part by concatenating queries like this:
AuditEntity.revisionNumber().maximize()
.add(AuditEntity.id().eq(id))
.add(AuditEntity.revisionType().ne(RevisionType.DEL))
into a big disjunction, with one term for each ID. When actually running that big disjunction in a query, I find that it returns much more than I've asked for, basically all non-DEL revisions ever created. The issue disappears when each maximize() query is included in its own dummy AuditConjunction (i.e. a conjunction with just one member).
Looking at the AggregatedAuditExpression.addToQuery() method, the problem seems to be that it's assuming the "parameters" parameter has an "and" connective, without actually checking it. AuditDisjunction creates a Parameters instance with an "or" connective, thus breaking the assumption made by AggregatedAuditExpression, and we end up with a broken query that ORs criteria it should be ANDing. My suggested fix is an explicit check for the connective in AggregatedAuditExpression.addToQuery(), and if it isn't "and", add yet another subquery whose connective is explicitly specified as "and".
I've attached a unit test that reliably triggers the issue for me. The .zip file is just the full Maven project I've created for testing, for the convenience of Maven users.
|