Ok, I found the where/why this happens. It comes from the CollectionEntry#resetStoredSnapshot method added as part of HHH-6361:
public void resetStoredSnapshot(PersistentCollection collection, Serializable storedSnapshot) {
LOG.debugf("Reset storedSnapshot to %s for %s", storedSnapshot, this);
snapshot = storedSnapshot;
collection.setSnapshot(loadedKey, role, snapshot);
}
So in the stated use case what is happening is that this CollectionEntry, as well as the incoming {collection}} reference, refer to the managed (previously merged) graph. However, the incoming storedSnapshot reference is coming from the original detached graph. Since that original graph had an empty snapshot, the net effect here is to overwrite the managed snapshot state with the empty thus all the entries are re-inserted into the database.
Still thinking through the best solution. I think the most appropriate solution will be to have CollectionEntry (and EntityEntry too?) keep track of a flag denoting whether they came about from a merge. In cases where that is true, we can skip the resetStoredSnapshot processing.
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira
Ok, I found the where/why this happens. It comes from the CollectionEntry#resetStoredSnapshot method added as part of
HHH-6361:So in the stated use case what is happening is that this CollectionEntry, as well as the incoming {collection}} reference, refer to the managed (previously merged) graph. However, the incoming storedSnapshot reference is coming from the original detached graph. Since that original graph had an empty snapshot, the net effect here is to overwrite the managed snapshot state with the empty thus all the entries are re-inserted into the database.
Still thinking through the best solution. I think the most appropriate solution will be to have CollectionEntry (and EntityEntry too?) keep track of a flag denoting whether they came about from a merge. In cases where that is true, we can skip the resetStoredSnapshot processing.