John,

Yes, it's a NH session per web request.
Storing NHibernate sessions in ASP.NET sessions is a terrible, terrible
idea.
Why would you want to "hold data in session" across web requests?? That
basically kills your scalability.
If you are concerned about costly queries, that's what the 2nd level cache
is for.

   Diego


On Fri, Feb 12, 2010 at 10:05, John Davidson <[email protected]> wrote:

> Diego
>
> You say web app pattern is NHibernate session per request. Is that each
> page request?
>
> Or do you mean that web pattern should be NHibernate session per User web
> session?
>
> The latter allows NHibernate to effectively hold data in session across web
> requests, and only has an additional cost when the web session is abandoned
> by the user without the apps knowledge, though the session will expire after
> 20 minutes(defualt).
>
> John Davidson
>
> On Thu, Feb 11, 2010 at 7:59 PM, Diego Mijelshon 
> <[email protected]>wrote:
>
>> In a web app, the usual pattern is session per request.
>>
>> You should research existing samples with patterns for web and desktop
>> apps (which are very different) before reinventing the wheel and investing
>> in an architecture that will bite you later.
>> Just sayin'.
>>
>> For desktop, two interesting approaches are Effectus and Chinook.
>>
>>    Diego
>>
>>
>>
>> On Thu, Feb 11, 2010 at 21:35, CSLem <[email protected]> wrote:
>>
>>> 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%[email protected]>
>>> ­>
>>> > > <nhusers%[email protected]<nhusers%[email protected]>
>>> <nhusers%252bunsubscr...@googlegroup­s.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]>
>>> <nhusers%[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]<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]<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]<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.

Reply via email to