After fixing HHH-6848, Hibernate throws IllegalStateException when merging entity
'x' if it has references to 2 detached entities 'y1' and 'y2'
obtained from different sessions, and y1 and y2 represent the same persistent entity. In
other words, y1 != y2.
I've pushed some FailureExpected test cases to org.hibernate.test.ops.MergeTest that
illustrate this. [1]
Before fixing HHH-6848, one of the representations would be merged and the other would be
ignored (probably overwritten).
I'm looking into a fix that will restore this functionality as well as provide logging
for this situation. I'll discuss logging in a separate email.
Merging multiple representations that have equivalent state would be straightforward.
Things are more complicated when the representations do not have equivalent state. I'd
like to discuss and get feedback before fixing this.
I am a little leery about allowing multiple representations that are not equivalent to be
merged because data could be lost. I would prefer to throw an exception by default, and
then provide a flag to override this behavior as suggested in HHH-8570. I discussed
briefly with Steve E., and he preferred to address this concern by logging a warning.
Opinions?
In any case, here are 2 possible strategies:
1) The last one copied will "win". First, the state from one will be copied onto
a pre-existing managed entity or a new managed copy, then later when the merge operation
is cascaded to the other representation, a copy of its state will overwrite the managed
entity state.
2) The first representation detected will "win". The idea here is that y1 and y2
are both representations of the same entity; only 1 can be merged. When the first is
detected, the merge operation is cascaded to its associations with cascade=MERGE or
cascade=AL, then its state will be copied onto a pre-existing managed entity or a new
managed copy. When a later representation is detected, it's state is not copied and
the merge operation is not cascaded to its associations with cascade=MERGE or
cascade=ALL.
I think 2) fits in better With the way merge currently works.
A problem with 1) is that we won't know when we are processing the last representation
until all cascade-merges are finished. By then, the session may contain entities from
cascading the merge operation from the earlier representations. This could result in
persisting transient entities or updating entites that are only associated with earlier
representations.
With 2) we always know when we are processing the first representation and can more easily
skip cascading the merge operation for representations detected later.
Comments?
Thanks,
Gail
[1]
https://github.com/hibernate/hibernate-orm/blob/0118376f8efd9b35d8be815c8...