The logic I create here will certainly be used later in a web version of this application. Keeping the session to a minimum will be essential there. I am really trying to implement a Session per Conversation sort of model with that web future in mind and was hoping to keep the session strictly in the data layer. If I use a long- running session the UI will have to be able to open and close the session.
If I open a session and begin a transaction, then disconnect (as opposed to closing and disposing) don't all the objects stay in the session? As I recall, I had some issues in the first attempt at this application because there were times when I wanted what was in the DB - not what was cached in the session - and I could not force NHIb to do that. For example, if I get a list of objects that is strictly for searching, then want to update a single object in the database I need to Get the object from the database at that time (to help eliminate StaleObjectStateExceptions) and give that to the presentation layer - not the object that was initially retrieved in the list. On Feb 11, 5:26 pm, Diego Mijelshon <[email protected]> wrote: > 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%252bunsubscr...@googlegroups.com> > > > > > > > > > . > > > > > > For more options, visit this group at > > > > > >http://groups.google.com/group/nhusers?hl=en.-Hidequotedtext - > > > > > > - 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.- 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.
