-->
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.  [ 5 posts ] 
Author Message
 Post subject: Can't save objects by cascade
PostPosted: Thu Jul 07, 2005 9:15 am 
I have two simple classes with such mappings:

Code:
   <class name="hibertest.ParentClass, hibertest" table="parent" >
      <id name="Id">
         <generator class="hilo" />
      </id>
      <property name="Name"/>
       <bag name="Children" lazy="true" cascade="all" inverse="true">
         <key column="pid"/>
         <one-to-many  class="hibertest.ChildClass, hibertest" />
      </bag>
   </class>
   
   <class name="hibertest.ChildClass, hibertest" table="child" >
      <id name="Id">
         <generator class="assigned" />
      </id>
      <property name="Name"/>
      <many-to-one name="ParentClass" class="hibertest.ParentClass, hibertest"  column="pid" />
   </class>


and code for work with objects:

Code:
         ParentClass pc = (ParentClass) session.Load(typeof(ParentClass), 2);

         ChildClass cc = new ChildClass();
         cc.Name = "MyTest";
         cc.Id = 6;
         cc.ParentClass = pc;
         pc.Children.Add(cc);

         session.Flush();


Method session.Flush() causes exception:

Code:
Unhandled Exception: NHibernate.ADOException: could not synchronize database state with session ---> NHibernate.HibernateException: SQL update or deletion failed (row not found)
   at NHibernate.Impl.NonBatchingBatcher.AddToBatch(Int32 expectedRowCount)
   at NHibernate.Persister.EntityPersister.Update(Object id, Object[] fields, Boolean[] includeProperty, Object oldVersion, Object obj, SqlString sqlUpdateString, ISessionImplementor session)
   at NHibernate.Persister.EntityPersister.Update(Object id, Object[] fields, Int32[] dirtyFields, Object[] oldFields, Object oldVersion, Object obj, ISessionImplementor session)
   at NHibernate.Impl.ScheduledUpdate.Execute()
   at NHibernate.Impl.SessionImpl.ExecuteAll(IList list)
   at NHibernate.Impl.SessionImpl.Execute()


I can save objects only by session.Save(), but it is not convenient. Who was confronted with such problem help me, please

P.S. Cascade deletion works properly

Serega


Top
  
 
 Post subject:
PostPosted: Thu Jul 07, 2005 7:01 pm 
Expert
Expert

Joined: Fri May 13, 2005 5:56 pm
Posts: 308
Location: Santa Barbara, California, USA
As far as i know, cascading transitive persistence only applies to save (update), delete and reattaching. Flush is something different. In your case, I would recommend using session.SaveOrUpdate(). I'm not sure why session.Save() would be more inconvienent than session.Flush() but I don't know your system.

-devon


Top
 Profile  
 
 Post subject: I need to use just cascades
PostPosted: Fri Jul 08, 2005 3:40 am 
I can use session.Save() or session.SaveOrUpdate() of cource, but I want use just cascades, it is most convenient approach for my tasks . There is an example in chm-reference in NHibernate distribution, chapter 6.3 "Cascading lifecycle". It is almost the same as my code example, but authors say it works.


Top
  
 
 Post subject:
PostPosted: Fri Jul 08, 2005 11:43 am 
Expert
Expert

Joined: Fri May 13, 2005 5:56 pm
Posts: 308
Location: Santa Barbara, California, USA
Okay, I get it, I misread your code and didn't see that you were loading the parent object from the db. In your case I think the problem is that cascading works by comparing the "unsaved-value" attribute to determine whether the object needs to be "cascaded."

Also, I think you are going to have problems because you are assigning the id of the child class. I don't know how NH would be able to determine if this was a transient object since you are assigning the id directly.

You can try adding the "unsaved-value" attribute to your <id> mapping-- most people use "0" or "-1"-- but I don't know what you would do for the <id> property of the ChildClass mapping.

-devon

Edit: I just read through section 6.4 of the reference-chm and the answer is in there. Apparently you will have to give NH a hint and there are three options-- two of them involve calls to session.Save() or session.Update()...


Top
 Profile  
 
 Post subject:
PostPosted: Fri Jul 08, 2005 12:23 pm 
actually if you read the docs (if they are accurate):

3.1.4.7. Assigned Identifiers
If you want the application to assign identifiers (as opposed to having NHibernate generate them), you may use the assigned generator. This special generator will use the identifier value already assigned to the object's identifier property. Be very careful when using this feature to not assign keys with business meaning (almost always a terrible design decision).

Due to its inherent nature, entities that use this generator cannot be saved via the ISession's SaveOrUpdate() method. Instead you have to explicitly specify to NHibernate if the object should be saved or updated by calling either the Save() or Update() method of the ISession.


Top
  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 5 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.