| I've concluded that what Envers should do here is delegate the collection comparison to ORM to determine the various revision rows needed. This eliminates the HashSet<> comparison that Envers uses and would eliminate the need for users to implement the equals and hashCode methods as I indicated previously to partly work around this issue. As I was working on the code for this implementation, I did stumble across something that sparked a question about Envers overall behavior. Lets assume we have this EmbeddedBean collection as the test case describes and we perform the following things on the collection:
bean.addEmbeddedBean( new EmbeddedBean( 1 ) );
bean.addEmbeddedBean( new EmbeddedBean( 2 ) );
We'd end up with a table like as follows
| Value |
Rev |
RevType |
Ordinal |
| 1 |
1 |
0 |
0 |
| 2 |
1 |
0 |
1 |
bean.addEmbeddedBean( new EmbeddedBean( 3 ) );
Leads to a table of
| Value |
Rev |
RevType |
Ordinal |
| 1 |
1 |
0 |
0 |
| 2 |
1 |
0 |
1 |
| 3 |
2 |
0 |
2 |
bean.removeEmbeddedBeanWithValue( 1 );
Finally ending up with
| Value |
Rev |
RevType |
Ordinal |
| 1 |
1 |
0 |
0 |
| 2 |
1 |
0 |
1 |
| 3 |
2 |
0 |
2 |
| 1 |
3 |
2 |
0 |
| 2 |
3 |
0 |
0 |
| 2 |
3 |
2 |
1 |
| 3 |
3 |
0 |
1 |
| 3 |
3 |
2 |
2 |
What I find redundant here is the fact that in Revision 3, we are effectively going to insert ( collection.size() - 1 ) * 2 numbers of rows into the table all for the removal of a single row. What I ponder is if this could be optimized to where the number of rows added could be reduced simple to collection.size() + 1, yielding this instead:
| Value |
Rev |
RevType |
Ordinal |
| 1 |
1 |
0 |
0 |
| 2 |
1 |
0 |
1 |
| 3 |
2 |
0 |
2 |
| 2 |
3 |
1 |
0 |
| 3 |
3 |
1 |
1 |
| 3 |
3 |
2 |
2 |
What this shows instead is
- Ordinal 0 was updated from 1 to 2.
- Ordinal 1 was updated from 2 to 3.
- Ordinal 2 was deleted.
I need to run more tests to see if optimizing this audit history has any side affects; however, if you have any feedback I'd be welcomed to hear it. |