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

Gail Badner (JIRA) noreply at atlassian.com
Tue May 11 22:32:24 EDT 2010


     [ http://opensource.atlassian.com/projects/hibernate/browse/HHH-1574?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

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: 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