-->
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.  [ 6 posts ] 
Author Message
 Post subject: NHibernate recommended best practices(real world)?
PostPosted: Wed Nov 29, 2006 3:18 pm 
Beginner
Beginner

Joined: Wed Nov 29, 2006 12:23 pm
Posts: 42
I am involved in the refactoring (rewriting) of an existing distributed .NET web application that has a back end exposed using web services - the system is implemented with a load balanced web layer, and a load balanced app layer. I am wondering what the accepted best practice for managing the session and passing around objects is. I've done quite a lot of reading and found this article

http://www.codeproject.com/aspnet/NHibe ... ctices.asp

on "NHibernate best practices with ASP.NET...", but it discusses putting the session management (opening and closing etc.) in the web layer. I've also seen BenDay's example,

http://blog.benday.com/archive/2005/10/25/3054.aspx

where he uses an IHTTPModule in the business layer to manage the session, which (while an IHTTPModule) is able to be used with either a web app or a windows forms app. While these examples are very useful for getting started with NHibernate in an ASP.NET world, I'm wondering if these approaches are actually what people are implementing in their production systems.

Also, I understand that by having all session management in the web service/business layer it will be necessary to use either transient objects or DTOs. If transient objects are used, (potentially) a lot of extra data will have to be transported between the layers. If i use DTOs, it will be necessary to always use a "select before update" approach (is this actually implemented within NHibernate, as in Hibernate?), requiring a larger amount of database utilisation. I'm also wondering what approach people are employing in this scenario.

The benefits of making use of NHibernate 1.2 are very obvious, but I realise that it is only in beta stage at the moment. Is there a proposed release date for it, as we will be working under reasonably tight deadlines (release early next year)?. I would feel more comfortable knowing that 1.2 will be released by then before proceeding with what at this stage, is a beta product (although very comprehensive, functional and full featured).

Any useful advice appreciated. Thanks.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Nov 29, 2006 7:53 pm 
Beginner
Beginner

Joined: Wed Nov 29, 2006 5:33 pm
Posts: 28
Location: Chicago, IL
Hello,

First a bit about my experience with NHibernate. We started working on a project about 3 months ago. I had been prototyping a new business layer and home grown code gen for our product for about 2 months on and off before that. We started with NHibernate 1.0 but quickly moved to 1.2. Not to say I have tried all the features exhaustively, but the only feature I have found a potential problem with so far is eager fetches within criteria queries.

As for your questions:

We do open and close our sessions and transactions within an IHttpModule. We also have a mechanism to allow the developer to begin and end new transactions explicitly though. We ran into the scenario where an exception is thrown during a save so we need to rollback the transaction. However we also need to be able to persist some database values in a few cases when this happens so the developer needs to have some control at times.

One of the concepts I would look out for in that code project article though is that of storing the sessions in System.Runtime.Remoting.Messaging.CallContext. The research that an associate of mine did is that this is OK for windows applications, but not good with ASP.NET applications. This is due to a behviour called context switching where the HTTP context can be copied from one thread to another after the HTTPModules run but before the page lifecycle starts. Because the CallContext is associated with the thread and not the HttpContext, you can get some unpredictable failures that occur more frequently only with the system under load. There are many good "context switching" articles on why this is a bad idea and yes, now that I know, it is disturbing that many projects (either web projects or libraries) use this approach to store contexts. Aside from that, great article.

It is possible to reassociate objects with different sessions (ISession.Lock(instance, LockMode.Read). This may provide an alternate or partial solution instead of/with DTO's. However, managing disconnected objects can be difficult. At one point we toyed with puting business objects in the Session or ViewState and reassociating them, but this proved to be difficult and/or just plain bad for a few different reasons. The hardest obstacle to overcome is that NHibernate by default generates proxies behind the scenes for entity references. These are extremely useful so that when you load a parent instance. The system does not need to load all of the other instances referenced until the parent's properties are accessed. The problem is that these proxies (last I looked) are not serializable and so can not be stored in the Session. The fix is to either jump through some hoops in order to get a version of that instance that is not a proxy or you need to tell NHibernate never to load proxies for that object which then potentially hurts performance. But if your Web Service layers are simple enough, you might be able to get away with serializing your business objects across the wire and reassociating them for persistence. Haven't tried that though; we just don't have that kind of architecture. We simply store ID's when needed.

Personally, I would be comfortable going to production with the 1.2.0 beta. But as full disclosure: we will only be having alpha users on our system anytime in the next 3- 6 months and I am reasonbly sure we will have a full release of NHibernate by the end of that time.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 30, 2006 5:25 am 
Newbie

Joined: Wed Nov 29, 2006 7:46 am
Posts: 9
Thanks onevextchuck.

I use the codeproject NHibernateBestPractices metod to store sessions in sessions in System.Runtime.Remoting.Messaging.CallContext too.

Im starting the project and if this system not works i have time to learn how do it well. Could you post any recomended post about "context switching" and
session storage?.

For other hand i have the same problem to storage object with lazy collections in the asp session object. Im thinking about create a metod in each class to store the current object in the asp session object using first NHibernateUtil.Initialze() in each collection.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 30, 2006 12:31 pm 
Beginner
Beginner

Joined: Fri Sep 02, 2005 12:13 pm
Posts: 44
Location: Denver, CO
For low traffic web sites, CallContext should be more than adequate for storing the open session for each web request. But for high traffic web sites, HttpContext is the way to go as the CallContext may change throughout the lifetime of the web request. I'm not sure where the cutoff point is between low and high but I've never run into a problem with peak traffic around one hit per second.

But regardless, the best practice when writing a web app is to store the open session within HttpContext and not CallContext directly. When I get around to updating my article, I'll be including this recommendation change along with an automatic context switcher that will work for both Win forms and Web forms.

Billy


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 30, 2006 4:13 pm 
Beginner
Beginner

Joined: Fri Jul 14, 2006 1:51 pm
Posts: 27
wmccafferty wrote:
For low traffic web sites, CallContext should be more than adequate for storing the open session for each web request. But for high traffic web sites, HttpContext is the way to go as the CallContext may change throughout the lifetime of the web request. I'm not sure where the cutoff point is between low and high but I've never run into a problem with peak traffic around one hit per second.

But regardless, the best practice when writing a web app is to store the open session within HttpContext and not CallContext directly. When I get around to updating my article, I'll be including this recommendation change along with an automatic context switcher that will work for both Win forms and Web forms.

Billy


So would you recommend this update to the best practices code? Is this the correct way to store the session in the HttpContext?

Code:
private static ISession threadSession
        {
            get { return ( ( ISession ) HttpContext.Current.Items[ threadSessionString ]); }
            set { HttpContext.Current.Items[ threadSessionString ] = value; }
        }


Top
 Profile  
 
 Post subject:
PostPosted: Thu Nov 30, 2006 4:30 pm 
Beginner
Beginner

Joined: Wed Nov 29, 2006 5:33 pm
Posts: 28
Location: Chicago, IL
sjusto,

We encapsulate our CallContext / HttpContext switching logic behind a SetData and GetData method.
(forgive the VB. They just won't listen to me. Unless you like VB. Then... um... I like it too. =) )
Code:
Private Shared Sub SetData(ByVal key As String, ByVal value As Object)
   If System.Web.HttpContext.Current IsNot Nothing Then
      System.Web.HttpContext.Current.Items.Add(key, value)
   Else
      System.Runtime.Remoting.Messaging.CallContext.SetData(key, value)
   End If
End Sub


Private Shared Function GetData(ByVal key As String) As Object
   If System.Web.HttpContext.Current IsNot Nothing Then
      Return System.Web.HttpContext.Current.Items.Item(key)
   Else
      Return System.Runtime.Remoting.Messaging.CallContext.GetData(key)
   End If
End Function


We just substitute that in anyplace you normally see the System.Runtime.Remoting.Messaging.CallContext.SetData(key, value) call.

This is one of the better articles that a co-worker sent to me about context switching. As I recall, it is not NHibernate specific, but it makes a lot of sense.
http://piers7.blogspot.com/2005/11/thre ... nd_02.html



Billy,
As long as you're reading these, thanks for the great article. I learned a lot from it.


Chuck


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