Why do you try to avoid a "long running session"? A session does not keep a DB connection open until you begin a transaction.
Diego On Thu, Feb 11, 2010 at 19:33, CSLem <[email protected]> wrote: > But the session is closed between the Get and the commit since I am > trying to avoid the long running session. That is I Get the object, > close the session and hand the object to the presentation layer. At > some point the object is passed back to the data layer. > > As a result I have a detached object and need to open a new session > and attach the object to the new session that I have. Doesn't that > mean I have to call some save method or lock? I have tried lock and, > if the collections have been retrieved, I get a "dirty collection" > error. > > On Feb 11, 4:22 pm, Jason Meckley <[email protected]> wrote: > > 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]> > <nhusers%[email protected]<nhusers%[email protected]> > > > > > > > . > > > > > For more options, visit this group at > > > > >http://groups.google.com/group/nhusers?hl=en.-Hidequoted text - > > > > > > - Show quoted text -- 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]<nhusers%[email protected]> > . > For more options, visit this group at > http://groups.google.com/group/nhusers?hl=en. > > -- 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.
