if the parent is managing the child entity and the parent is retrieved
from the database there is no reason to explicitly call any of the
Save operations. NH will do this for you. example
var id = 1;
var nameOfChild = "Jason";
using(var tx = session.BeginTransaction())
{
try
{
var parent = session.Get<Parent>(id);
parent.Add(nameOfChild);
tx.Commit();
}
catch
{
tx.Rollback();
throw;
}
}
where parent.Add looks like
class Parent
{
private IList<Child>() children = new List<Child>();
public virtual void Add(string name)
{
var child = new Child{Name = name, Parent = this};
children.Add(child);
}
}
On Feb 11, 4:59 pm, CSLem <[email protected]> wrote:
> Sorry for the long delay. I am still struggling to get the maps
> correct and SQL performing as I need.
>
> I do add the child to the list. Right now, after some changes to
> cascade options and logic I have the tests doing all three operations.
> However, it only works in a long running session.
>
> My simple view of the app is this:
> 1) Get an object from the data layer. This starts with Parent so the
> first object I get is the parent with no lazy collections loaded.
> 2) Close the session
> 3) Let the user do whatever with the parent object
> 4) IF the user needs the collection or collections, open a new
> session, retrieve the collections, close the session
> 5) Let the user make necessary changes to Parent and Children
> 6) When the user indicates they want to save open a new session, call
> session.SaveOrUpdate(parent) and have the data layer cascade whatever
> is changed.
>
> I would assume this is how an httpsession is handled. I am not in a
> web session but still don't want the session to remain open since the
> users often open the application and leave it up all day, creating a
> very long connection if I don't destroy the session after each action.
>
> If I close the session after I get the object(s) then when I pass the
> Parent back to the data layer and call SaveOrUpdate(parent) NHibernate
> issues an UPDATE statement for every object in the graph - Parent and
> EVERY child that has been retrieved. I have tried used
> SaveOrUpdateCopy instead but then seem to have problems in my unit
> test if I attempt to update the object twice. That is, get the Parent
> and Children, update something on one of the Children, send it back to
> the database. Update something on the Parent, send it back to the
> database. At this point (using SaveOrUpdateCopy) I get a "row was
> updated or deleted...." error.
>
> I just can't seem to find the right combination of attributes and
> method calls to do what I assume is a pretty normal process.
>
> Here is a sample test.
>
> Parent parent = CurrentSession.GetById(parentId); //includes logic to
> open a session, retrieve and close
> parent.Amplify(); //retrieves the child collection(s) using a
> separate session, close
> parent.child.comment = "NEW TEXT";
> parent.ApplyChanges(); //opens a session, calls
> session.SaveOrUpdate(parent)
> parent.someproperty = "New value";
> parent.ApplyChanges();
>
> The second ApplyChanges opens the session correctly but either fails
> with the row was updated error (using SaveOrUpdateCopy) or issues
> UPDATE statements for EVERY object in parent and child collections.
> (using SaveOrUpdate).
>
> Today I switched my timestamp to a version column thinking that maybe
> the timestamp was not performing well as a concurrency check but the
> behavior is still exactly the same. Short of opening a session when I
> start the application and closing it when I am done I am not sure
> where to go from here.
>
> On Feb 5, 3:23 pm, Diego Mijelshon <[email protected]> wrote:
>
> > You need to add the Child to ChildList. Otherwise, how would NHibernate find
> > it?
>
> > Diego
>
> > On Fri, Feb 5, 2010 at 13:07, CSLem <[email protected]> wrote:
> > > I have what I think is a VERY simple mapping. This particular one uses
> > > DB generated Ids for all tables and, depending on how I set up inverse/
> > > cascade I can get saves to work all the time but either inserts or
> > > deletes fail. Insert sometimes fails with a Cannot insert NULL value
> > > in ChildId column or appears to work but issues no INSERT to the SQL
> > > database. When I get the inserts to work the deletes fail due to the
> > > foreign key relationship on the child.
>
> > > I always want the Parent to manage the relationship to the DB. That
> > > is, for this application, there is never a need to try to insert/
> > > update/delete except through the parent so when the update statement
> > > is issued it is always session.saveorupdate(Parent); I would expect
> > > that to issue the necessary INSERT Parent..., INSERT Child...; etc
> > > with the correct ID or the necessary UPDATE/DELETE statements.
>
> > > I am using the NHibernate V2.1.0.4000 and NHibernate.Linq V1.0.0.4000,
> > > although I don't know that Linq matters on this side of the equation.
>
> > > The current classes/maps are as follows and this version manages
> > > everything except the insert.
>
> > > public class Parent {
> > > public virtual int ParentId { get; set; }
> > > public virtual DateTime? LastModified { get; set; }
> > > public virtual IList<Child> ChildList { get; set; }
> > > }
>
> > > public class Child {
> > > public virtual int ChildId { get; set; }
> > > public virtual Parent Parent { get; set; }
> > > public virtual DateTime? Created { get; set; }
> > > public virtual string CreatedBy { get; set; }
> > > public virtual CommentType CommentType { get; set; }
> > > public virtual string Comment { get; set; }
> > > public virtual DateTime? LastModified { get; set; }
> > > }
>
> > > <?xml version="1.0" encoding="utf-8" ?>
> > > <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
> > > assembly="NewAssembly.Core"
> > > namespace="NewAssembly.Core">
>
> > > <class name="Parent" table="t_Parent">
> > > <id name="ParentId" type="string" unsaved-value="0">
> > > <generator class="native"></generator>
> > > </id>
> > > <timestamp name="LastModified"/>
> > > <bag name="ChildList" inverse="true” cascade="all-delete-orphan">
> > > <key column="ParentId"/>
> > > <one-to-many class="Child"/>
> > > </bag>
> > > </class>
> > > </hibernate-mapping>
>
> > > <class name="Child" table="t_Child">
> > > <id name="ChildId">
> > > <generator class="native"/>
> > > </id>
> > > <timestamp name="LastModified"/>
> > > <property name="Created"/>
> > > <property name="CreatedBy"/>
> > > <property name="CommentType" column="Type"/>
> > > <property name="Comment"/>
> > > <many-to-one name="Parent" column="ParentId"/>
> > > </class>
> > > </hibernate-mapping>
>
> > > When the Child object is constructed I do set the Parent property. On
> > > an insert, however, the ParentId is obviously not generated yet and
> > > the call to session.SaveOrUpdate(Parent) issues an INSERT to SQL for
> > > the parent record and, depending on settings, either no INSERT for the
> > > child or an INSERT with a NULL value constraint error.
>
> > > What am I missing to get all three operations (insert, save, delete)
> > > working?
>
> > > -C-
>
> > > --
> > > 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]<nhusers%[email protected]>
> > > .
> > > For more options, visit this group at
> > >http://groups.google.com/group/nhusers?hl=en.-Hide quoted text -
>
> > - Show quoted text -
--
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.