]
Gail Badner resolved HHH-1574.
------------------------------
Resolution: Fixed
Fixed in trunk and Branch_3_5.
Alex, thanks for the fix and the test case!
There may be a similar issue with immutable natural IDs containing a component. If someone
runs into that, please open a new issue.
AbstractEntityPersister.getNaturalIdentifierSnapshot doesn't work
with many-to-one ids (Alex Burgel)
----------------------------------------------------------------------------------------------------
Key: HHH-1574
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-1574
Project: Hibernate Core
Issue Type: Patch
Affects Versions: 3.1.2
Reporter: Alex Burgel
Assignee: Gail Badner
Fix For: 3.5.2, 3.6
Attachments: resolveentity.patch, resolveentity32.patch, testcase.zip
i just upgraded from 3.0.5 to 3.1.2, and i started seeing this problem. i'm not
exactly sure where the bug is here, but this is what i'm seeing:
i have a class, Subscription, which has a natural-id of class Subscriber and Edition
(excerpts of relevant mapping files below).
when Subscription is unloaded, if i make a change, then commit the session, i see this
exception:
HibernateException: immutable natural identifier of an instance of Subscription was
altered
this gets thrown from DefaultFlushEntityEventListener.checkNaturalId() line 80.
i traced through that method, this is what happens:
1. in checkNaturalId, loaded == null , so getNaturalIdSnapshot() is called
2. this ends up generating some sql that selects the SubscriptionId and EditionId from
the Subscription row.
3. the sql is generated in AbstractEntityPersister.getNaturalIdentifierSnapshot(), which
calls hydrate for each returned column of the natural-id,
4. but hydrate only returns the id, instead of the actual entity
5. so this array of ids (instead of entities) ends up back in
DefaultFlushEntityEventListener.checkNaturalId() as 'loaded', which gets compared
to 'current'
the trouble is that 'current' contains the entities, but 'loaded' only
contains the ids of those entites, so the natural-id check fails, and i get the
exception.
this only happens when 'loaded' is null in checkNaturalId().
the javadocs for hydrate say you have to call "resolve" afterwards... this
isn't being done, so maybe thats the fix. if the natural-id is not just simple
properties, then resolve should also be called.
<class name="Subscription" table="Subscriptions"
batch-size="10">
<id name="id" column="Id"
type="int"><generator class="native" /></id>
<natural-id>
<many-to-one name="subscriber" class="Subscriber"
column="SubscriberId" />
<many-to-one name="edition" class="Edition"
column="EditionId" />
</natural-id>
....
</class>
<class name="Subscriber" table="Subscriber">
<id name="id" column="id"
type="int"><generator class="native" /></id>
<map name="subscriptions" inverse="true"
cascade="all,delete-orphan" batch-size="10">
<key column="SubscriberId" />
<map-key-many-to-many column="EditionId"
class="Edition" />
<one-to-many class="Subscription" />
</map>
</class>
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: