Injecting target into proxy in org.hibernate.envers.tools.Tools#getTargetFromProxy can
cause duplicate entities in session
--------------------------------------------------------------------------------------------------------------------------
Key: HHH-4803
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-4803
Project: Hibernate Core
Issue Type: Bug
Components: envers
Affects Versions: 3.5.0-Beta-3
Reporter: Gail Badner
I believe that problems can arise if Tools.getTargetFromProxy(...) injects the target into
the proxy. It is possible that the target entity will be duplicated in the session and
cause an exception to be thrown.
Here is a (very contrived) scenario where this can happen:
X has a lazy many-to-one association with Y with cascade="all"
Both X and Y have a non-lazy many-to-one association with Z with cascade ==
"all"
s: original session
sTemp: temporary session
The entities, x, y, and z have already been persisted with the following associations:
x.y == y
x.z == null
y.z == z
In a new session/transaction:
X x = ( X ) s.get( X.class, xId );
Y yProxy = x.getY();
Z z = ( Z ) s.get( Z.class, zId );
z.setName( "new name" );
x.setZ( z );
s.update( x );
When changes to x are audited, Tools.getTargetFromProxy(...) is called to get the entity
target for yProxy from a temporary session (sTemp) and inject that target back into
yProxy.
Because of the non-lazy association between Y and Z, yProxy.z is also initialized in the
temporary session. yProxy.z should refer to the same instance as z, but they are different
instances because they were loaded into different sessions. In addition, the two instances
have different state:
- z has a non-flushed update
- yProxy.z has the same state as loaded (w/o the update)
In other words:
z != yProxy.z && ! z.equals( yProxy.z )
Later, when an operation cascades to yProxy.z (e.g., during flush) and it's added to
the session, an exception will be thrown because an updated version of the same entity is
already present.
The safest way to avoid subtle problems like this is for Tools.getTargetFromProxy(...) to
leave the proxy uninitialized (instead of injecting the target).
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira