In practice....If NH found a proxy, in some place, that entity was loaded
trough NH and mean that entity need an update.

2009/5/18 Fabio Maulo <[email protected]>

> There are two way to create a clone.Deep copy or shallow copy ?
>
> 2009/5/18 domonkos <[email protected]>
>
>
>> NHibernate removes entities of a many-to-one relationship from
>> previous owner after cloning.
>> I have a business object which holds different kind of lists:
>>
>> public class BusinessObject
>> {
>>        int ID{get;set;}
>>        IList Entites{get;set;}
>>        ...
>> }
>>
>> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" auto-
>> import="false">
>>        <class name="MainNamespace.BusinessObject, Model"
>> table="Businessobject">
>>                <jcs-cache usage="read-write" />
>>                <id name="ID" type="Int32" unsaved-value="0">
>>                        <generator class="identity" />
>>                </id>
>>        ...
>>                <list name="Units" lazy="true">
>>                        <key column="BusinessObjectID" />
>>                        <index column="BusinessObjectIndex" />
>>                        <one-to-many class="MainNamespace.BusinessObject,
>> Model" />
>>                </list>
>>
>> This is an example entity:
>>
>> public class Entity
>> {
>>        int ID{get;set;}
>>        ...
>> }
>>
>> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" auto-
>> import="false">
>>        <class name="MainNamespace.Entity, Model" table="Entity">
>>                <jcs-cache usage="read-write" />
>>                <id name="ID" type="Int32" unsaved-value="0">
>>                        <generator class="identity" />
>>                </id>
>>        ...
>>                <many-to-one name="BusinessObject"
>> class="MainNamespace.BusinessObject, Model" column="BusinessObjectID" /
>> >
>>
>> One noteable thing is that the entity contains a backward reference to
>> the BusinessObject in its mapping.
>>
>> I don't use cascade because of the complexity of my lists and business
>> workflows.
>> The cloning process starts by creating 'new version' of business
>> entites by removing them from the session and set their ID-s to zero
>> to mar them as 'unsaved'.
>>
>> Here is an example of cloning a list in my business object:
>>
>> foreach(Entity entity in businessObjects)
>> {
>>        //New entity nothing has to be done
>>        if(entity.ID == 0) continue;
>>
>>        //Evict old entity from session
>>        NHibernateSession.Evict(entity);
>>        //Mark as unsaved
>>        entity.ID = 0;
>> }
>>
>> The cloning process for the main business object goes by the same way
>> which means an evict and setting its ID to 0.
>> So after this I'll end up with an unsaved instance of my
>> businessobject and all of my list entites.
>>
>> This is the point where I will do a 'full save' on all entites. As I
>> can not use cascade saving I iterate through all basic entites and
>> save them.
>> But at first I save the whole BusinessObject.
>>
>> //Copy to a temporary list
>> IList entites = businessObject.Entites;
>> //Empty the list
>> businessObject.Entites = null;
>>
>> //Save the BusinessObject
>> NHibernateSession.Save(businessObject);
>>
>> //Saving Lists
>> if(entites != null)
>> {
>>        foreach(Entity entity in entites)
>>        {
>>                NHibernateSession.Save(entity);
>>        }
>>
>>        //Set back the list
>>        businessObject.Entites = entites
>> }
>>
>> After this point whenever a Flush is happening NHibernate will
>> generate a query which removes all entites from the previous version
>> of the BusinessObject.
>>
>> So for instance if the original ID of a BusinessObject was 1980 and
>> I've set it to 0 in the clone process, the ID will be 1981 when I do
>> the full save which is correct, but when a Flush is happening in the
>> full save or I commit the transaction a sql query like this will also
>> will be ran by NHibernate:
>> exec sp_executesql N'UPDATE [Entity] SET BusinessObjectID = null,
>> BusinessObjectIndex = null WHERE BusinessObjectID = @p0', N'@p0
>> int',@p0 = 1980
>>
>> Where the parameter is the ID of the prevoius BusinessObject. In this
>> case every of my entites will be removed from the previous business
>> object.
>>
>> I don't understand why is this happening. This beahavior did not exist
>> in the earlier version of NHibernate. I thought that evict removes the
>> previous version of my BusinessObject from the session,
>> I'm not sure how NHibernate 'knows' that the owner has been changed.
>> How can this behavior fixed?
>>
>>
>>
>> >>
>>
>
>
> --
> Fabio Maulo
>



-- 
Fabio Maulo

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"nhusers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/nhusers?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to