| I see precisely why this happens. The gist of the problem is a collection re-create happens where all the rows in the base table are deleted and then re-inserted with the way the collection gets reset. When this operation gets reinterpreted by Envers, it generates a series of audit operations that mimic that:
| RuleName_ID * |
REV * |
REVTYPE |
| 1 |
1 |
DEL |
| 2 |
1 |
DEL |
| 1 |
1 |
ADD |
| 2 |
1 |
ADD |
The problem here is that when Envers built the table for this collection, only the columns marked with * participate in the primary key and therefore because those 4 operations occur within the boundary of the same transaction, therefore the same revision – we face the problem where a NonUniqueObjectException gets thrown and resolved as an EntityExistsException. The problem here is how best to resolve this. I see 2 options forward: 1. Introduce a way to translate the above 4 changes into 2 MOD changes before save. 2. Introduce a non-backward compatible setting that controls if REVTYPE is in the primary-key. In order to consider (1) I need to do a bit of research but the idea is to see if we can determine before save that we have this use case and consolidate those collection changes into a smaller more concise form. In short, we'd see that our collection of RuleName entities has the same entity-id with both a DEL and ADD operation. We can build a difference between the two and rewrite the collection change as a MOD instead. In order to consider (2), we'd simply add a configuration setting that would control whether or not we add REVTYPE to the primary key of an audit table mapping that represents a collection. We'd most likely need to have this setting disabled by default in order to preserve backward compatibility and add a migration note so users know how to alter their schema to take advantage of the behavior if they wish. As a side note I believe (2) also highlights the importance of Envers being capable of tracking what "version" of the schema it has been using and have a way to effectively migrate itself from version-to-version. By being able to do that, we'd be able to easily make rev-type a primary-key value, add a migration task and for users who upgrade – it just happens, bugfixed, and no manual migration necessary. But that's a long-term goal but we need a short-term fix now. |