-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 
Author Message
 Post subject: possible bug with parent-child relationships
PostPosted: Thu Nov 09, 2006 11:55 am 
Beginner
Beginner

Joined: Thu Nov 02, 2006 5:11 pm
Posts: 32
Location: Toronto
I posted this problem previously, but have been unable to solve it. I am wondering if this is a bug in NHibernate:

I have 2 classes that form a parent-child relationship. I am trying to move all children from one instance of a parent to another parent instance, but I'm getting an ObjectDeletedException.

Hibernate version: 1.0.2

Mapping documents:

I have a Patient class and a PatientProfile class. The Patient has a set of PatientProfiles, mapped as a parent-child relationship, as shown:

Code:
  <class name="Patient" proxy="Patient" table="Patient_">
    <id name="OID" column="OID_" type="Int64">
      <generator class="hilo">
        <param name="max_lo">100</param>
      </generator>
    </id>
    <version name="Version" column="Version_"/>

    <set name="Profiles" lazy="true" inverse="true" cascade="all-delete-orphan" access="nosetter.camelcase-underscore">
      <key column="PatientOID_"/>
      <one-to-many class="PatientProfile"/>
    </set>
  </class>

  <class name="PatientProfile" proxy="PatientProfile" table="PatientProfile_">
    <id name="OID" column="OID_" type="Int64">
      <generator class="hilo">
        <param name="max_lo">100</param>
      </generator>
    </id>
    <version name="Version" column="Version_"/>

    <many-to-one name="Patient" class="Patient" column="PatientOID_" not-null="true" fetch="join"/>
  </class>



Code between sessionFactory.openSession() and session.close():

The purpose of the code is to move all PatientProfiles from one Patient to another Patient, and delete the patient with no profiles, as shown here:

Code:
using (ITransaction trans = session.BeginTransaction())
{
        Patient a = (Patient)session.Load(typeof(Patient), idA);
        Patient b = (Patient)session.Load(typeof(Patient), idB);

        // copy patient b profiles into temp arraylist
        ArrayList bProfiles = new ArrayList(b.Profiles);

        // Move profiles from patient b to patient a
        foreach (PatientProfile bProfile in bProfiles)
        {
            if (bProfile.Patient != null)
            {
                b.Profiles.Remove(bProfile);
            }
            bProfile.Patient = a;
            a.Profiles.Add(bProfile);
        }
        session.Delete(b);

    trans.Commit();
}


Full stack trace of any exception that occurs:

Code:
A first chance exception of type 'NHibernate.ObjectDeletedException' occurred in NHibernate.dll
System.Transactions Critical: 0 : <TraceRecord xmlns="http://schemas.microsoft.com/2004/10/E2ETraceEvent/TraceRecord" Severity="Critical"><TraceIdentifier>http://msdn.microsoft.com/TraceCodes/System/ActivityTracing/2004/07/Reliability/Exception/Unhandled</TraceIdentifier><Description>Unhandled exception</Description><AppDomain>HibernateTest.vshost.exe</AppDomain><Exception><ExceptionType>NHibernate.ObjectDeletedException, NHibernate, Version=1.0.2.0, Culture=neutral, PublicKeyToken=154fdcb44c4484fc</ExceptionType><Message>deleted object would be re-saved by cascade (remove deleted object from associations): 405, of class: HibernateTest.PatientProfile</Message><StackTrace>   at NHibernate.Impl.SessionImpl.ForceFlush(EntityEntry e)
   at NHibernate.Impl.SessionImpl.Save(Object obj)
   at NHibernate.Impl.SessionImpl.SaveOrUpdate(Object obj)
   at NHibernate.Engine.Cascades.CascadingAction.ActionSaveUpdateClass.Cascade(ISessionImplementor session, Object child, Object anything)
   at NHibernate.Engine.Cascades.Cascade(ISessionImplementor session, Object child, IType type, CascadingAction action, CascadeStyle style, CascadePoint cascadeTo, Object anything)
   at NHibernate.Engine.Cascades.CascadeCollection(CascadingAction action, CascadeStyle style, PersistentCollectionType collectionType, IType elemType, Object child, CascadePoint cascadeVia, ISessionImplementor session, Object anything)
   at NHibernate.Engine.Cascades.Cascade(ISessionImplementor session, Object child, IType type, CascadingAction action, CascadeStyle style, CascadePoint cascadeTo, Object anything)
   at NHibernate.Engine.Cascades.Cascade(ISessionImplementor session, IClassPersister persister, Object parent, CascadingAction action, CascadePoint cascadeTo, Object anything)
   at NHibernate.Engine.Cascades.Cascade(ISessionImplementor session, IClassPersister persister, Object parent, CascadingAction action, CascadePoint cascadeTo)
   at NHibernate.Impl.SessionImpl.PreFlushEntities()
   at NHibernate.Impl.SessionImpl.FlushEverything()
   at NHibernate.Impl.SessionImpl.Flush()
   at NHibernate.Transaction.AdoTransaction.Commit()
   at HibernateTest.Program.Main(String[] args) in



Interestingly, if I remove the line

Code:
session.Delete(b);


from the above code, no exception is thrown, but NHibernate generates incorrect SQL:

Code:
NHibernate: UPDATE ris4.dbo.Patient_ SET Version_ = @p0 WHERE OID_ = @p1 AND Version_ = @p2
@p0 = '9'
@p1 = '102'
@p2 = '8'
NHibernate: UPDATE ris4.dbo.Patient_ SET Version_ = @p0 WHERE OID_ = @p1 AND Version_ = @p2
@p0 = '1'
@p1 = '304'
@p2 = '0'
NHibernate: DELETE FROM ris4.dbo.PatientProfile_ WHERE OID_ = @p0 AND Version_ = @p1
@p0 = '405'
@p1 = '0'


The first 2 statements simply update the Version of the Patients, which is correct. However, the last statement should just update the foreign key reference of the PatientProfile. Why does it delete it?


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 29, 2006 10:45 am 
Beginner
Beginner

Joined: Wed Nov 29, 2006 10:32 am
Posts: 34
See the following discussion on the Hibernate list - it is quite unfriendly, especially some guy "christian" (he seems to be unaware of standard composition semantics) ... but in essence, they say "it's not a bug, it's a feature" and, "don't use delete-orphans".

http://forum.hibernate.org/viewtopic.php?t=961777

Regards
Harald


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.