[hibernate-issues] [Hibernate-JIRA] Updated: (HHH-1574) AbstractEntityPersister.getNaturalIdentifierSnapshot doesn't work with many-to-one ids

Alex Burgel (JIRA) noreply at atlassian.com
Thu Nov 2 15:20:04 EST 2006


     [ http://opensource.atlassian.com/projects/hibernate/browse/HHH-1574?page=all ]

Alex Burgel updated HHH-1574:
-----------------------------

    Attachment: resolveentity32.patch

a newer version of the patch for 3.2, with the test cases included in the patch.

this is based on tags/v32final/Hibernate3

> AbstractEntityPersister.getNaturalIdentifierSnapshot doesn't work with many-to-one ids
> --------------------------------------------------------------------------------------
>
>          Key: HHH-1574
>          URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-1574
>      Project: Hibernate3
>         Type: Bug

>     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:
   http://opensource.atlassian.com/projects/hibernate/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira




More information about the hibernate-issues mailing list