]
Russ Egan commented on HHH-1574:
--------------------------------
I'm running into this too...not seeing a great workaround, apart from ditching the
immutable attribute.
AbstractEntityPersister.getNaturalIdentifierSnapshot doesn't work
with many-to-one ids
--------------------------------------------------------------------------------------
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
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: