Fluent NHibernate Session Factory Performance

978 views
Skip to first unread message

Jack Hughes

unread,
Jul 19, 2010, 10:02:05 AM7/19/10
to fluent-nhibernate
Hello all,

I've written a Windows service to use fluent NHibernate. The project
consists of 6 entities with associated mappings. When the service starts
it connects to the database using fluent. The code is the same as the
Fluent NHibernate console program sample.

Start up times are pretty slow ~10 seconds. So slow that starting up the
service sometimes fails due to timeout. I've tracked this down to the
session creation process, the method called CreateSessionFactory in the
sample program.

In order to make sure that it wasn't something I was doing I did the
same performance test using the Fluent NHibernate program itself.
Performance is about the same at 8093ms.

Anybody any ideas what I can do to speed things up? From what I can see,
it looks like it is the generation of the XML mapping files where the
majority of the time is being spent.

Regards,

Jack Hughes

Bojan Rajkovic

unread,
Jul 19, 2010, 8:24:46 PM7/19/10
to fluent-n...@googlegroups.com

--
You received this message because you are subscribed to the Google Groups "Fluent NHibernate" group.
To post to this group, send email to fluent-n...@googlegroups.com.
To unsubscribe from this group, send email to fluent-nhibern...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/fluent-nhibernate?hl=en.


Hi Jack,

You could use FNH to generate the .hbm.xml files once and then embed the generated .hbm.xml and use the classic NHibernate way. Of course, you'd need to change your session factory construction to use the embedded mappings instead of generating new ones, but that's ~trivial. If I recall correctly, this yielded me a significant speedup on my FNH app. Of course, it's a little less fluent when you do that, but you don't have to write any of the XML by hand.

Cheers,
Bojan
Message has been deleted

mcintyre321

unread,
Jul 26, 2010, 9:35:53 AM7/26/10
to Fluent NHibernate
var assemblyModifiedDate = //TODO:
http://stackoverflow.com/questions/804192/how-can-i-get-the-assembly-last-modified-date
if (!File.Exists("mapping.xml") ||
File.GetLastModified("mapping.xml") != assemblyModifiedDate )
{
//TODO: use FNH to write mapping.xml and set its modified date to
assembly modified date
}
cfg.AddXmlFile("mappings.xml");

then you'll only have to do it once per build.

On Jul 20, 1:24 am, Bojan Rajkovic <severedcr...@gmail.com> wrote:
> On Mon, Jul 19, 2010 at 10:02 AM, Jack Hughes <jhug...@openxtra.co.uk>wrote:
>
>
>
>
>
> > Hello all,
>
> > I've written a Windows service to use fluent NHibernate. The project
> > consists of 6 entities with associated mappings. When the service starts it
> > connects to the database using fluent. The code is the same as the Fluent
> > NHibernate console program sample.
>
> > Start up times are pretty slow ~10 seconds. So slow that starting up the
> > service sometimes fails due to timeout. I've tracked this down to the
> > session creation process, the method called CreateSessionFactory in the
> > sample program.
>
> > In order to make sure that it wasn't something I was doing I did the same
> > performance test using the Fluent NHibernate program itself. Performance is
> > about the same at 8093ms.
>
> > Anybody any ideas what I can do to speed things up? From what I can see, it
> > looks like it is the generation of the XML mapping files where the majority
> > of the time is being spent.
>
> > Regards,
>
> > Jack Hughes
>
> > --
> > You received this message because you are subscribed to the Google Groups
> > "Fluent NHibernate" group.
> > To post to this group, send email to fluent-n...@googlegroups.com.
> > To unsubscribe from this group, send email to
> > fluent-nhibern...@googlegroups.com<fluent-nhibernate%2Bunsubscr i...@googlegroups.com>
> > .

Henrique Cabral

unread,
Aug 12, 2010, 4:26:03 PM8/12/10
to fluent-n...@googlegroups.com
Hey everyone,

Following this thread, I'm interested in knowing if anyone has any
further ideas about performance. My app is made in asp.net, and I'm
trying to follow the motto that "database connections are too
expensive", and each request that needs data opens a Session, then
maps objects, and so on.

I'm prematurely reaching the conclusion that this is not viable.
Creating XML mappings for each build defeats the elegant purpose of
FNH. I started to think in Java (app server) and service tiers, since
database connections are not really that expensive to me yet.

So, any thoughts?

Cheers,
Henrique

James Gregory

unread,
Aug 12, 2010, 4:31:37 PM8/12/10
to fluent-n...@googlegroups.com
I think you're mistaken about where FNH is used, and when it does it's
work. Fluent NHibernate should only be initialised upon application
startup; in the case of a web application that'd be in your
Global.asax or something similar. The SessionFactory is then stored
(in a global, singleton, static, whatever) and reused throughout the
application lifecycle. Sessions are only used to open database
connections, there's no "mapping" taking place.

> --
> You received this message because you are subscribed to the Google Groups
> "Fluent NHibernate" group.
> To post to this group, send email to fluent-n...@googlegroups.com.
> To unsubscribe from this group, send email to

> fluent-nhibern...@googlegroups.com.

Henrique Cabral

unread,
Aug 12, 2010, 7:26:28 PM8/12/10
to fluent-n...@googlegroups.com
James,

I think you're right, I will have to check how this is implemented.
Our group is formed mostly by Java developers, and ASP.NET is pretty
new to everyone. Thanks for the tip, will keep doing research on FNH.

Cheers,
Henrique Cabral

Henrique Cabral

unread,
Aug 13, 2010, 1:19:01 AM8/13/10
to fluent-n...@googlegroups.com
Hello everyone,

What about this approach:

http://nhforge.org/blogs/nhibernate/archive/2010/07/11/nhibernate-bootstrapper-unitofwork-and-sessionperrequest.aspx

Versus the Global.asax? Or the Burrow framework?

Cheers,
Henrique

Jason Dentler

unread,
Aug 13, 2010, 7:09:04 AM8/13/10
to fluent-n...@googlegroups.com
Henrique,

There are many options when starting an NHibernate project. I assume you are using ASP.NET WebForms and have settled on mapping with Fluent NHibernate. You want to implement session-per-request, which can be done a number of ways.

Here's how this looks:
On application startup:
  1. Configure NHibernate following the FNH docs. This takes care of all the mapping magic. The fluent syntax ends by building a session factory. 
  2. Hold on to the session factory for as long as your application is alive. It is your one and only session factory. This can be as simple as a static field in the global.asax, though I prefer to put it in my IoC container. 
On request start:
  1. Using the session factory, open a session. This is cheap. It doesn't open a database connection. Don't worry about opening a session when it's not used.
  2. Make the session available for the lifetime of the request. You have two good options:
    1. Put it in your IoC container
    2. Use NHibernate contextual sessions, so you would call sessionFactory.GetCurrentSession() to find the session for this request.  http://nhforge.org/doc/nh/en/index.html#architecture-current-session
On request end:
  1. Close or Dispose the session. 

Thanks,
Jason

On Fri, Aug 13, 2010 at 12:19 AM, Henrique Cabral <hca...@gmail.com> wrote:
Hello everyone,

What about this approach:

http://nhforge.org/blogs/nhibernate/archive/2010/07/11/nhibernate-bootstrapper-unitofwork-and-sessionperrequest.aspx

Versus the Global.asax? Or the Burrow framework?

Cheers,
Henrique



On Thu, Aug 12, 2010 at 7:26 PM, Henrique Cabral <hca...@gmail.com> wrote:
> James,
>
> I think you're right, I will have to check how this is implemented.
> Our group is formed mostly by Java developers, and ASP.NET is pretty
> new to everyone. Thanks for the tip, will keep doing research on FNH.
>
> Cheers,
> Henrique Cabral
>

Henrique Cabral

unread,
Aug 13, 2010, 11:02:30 AM8/13/10
to fluent-n...@googlegroups.com
Jason,

Thanks for the inputs. I consider my FNH with AutoMap implementation
pretty clean and straight-forward, and I followed the docs well. For
my WCF services, the static calls had taken care of the handling of a
unique SessionFactory instace, but that was totally broken for ASP.NET
pages.

Right now I'm coding myself the IHttpModule to handle the
SessionPerRequest, will see how it goes. One of my problems is that I
have at least 4 databases, each has mapped entities, so you can
imagine that my Fluent.Configure() may get tricky.

Cheers,
Henrique Cabral

Henrique Cabral

unread,
Aug 13, 2010, 1:46:06 PM8/13/10
to fluent-n...@googlegroups.com
Hi,

Could any of you guys share some real-life experience in production
servers with ASP.NET and NHibernate? I'm testing the solution now with
3 SessionFactory instances (I have 3 databases). If I open one session
per request, say we have a page with 30 elements, and say the web app
modestly has 10 simultaneous users, we may reach up to 300 opened
sessions at any given moment. If you have an insight about this and
would like to share, I would appreciate it. Or maybe point at some
papers or blog entries.

Cheers,
Henrique Cabral

James Gregory

unread,
Aug 13, 2010, 2:17:33 PM8/13/10
to fluent-n...@googlegroups.com
Why would a page open 30 sessions? You have one session per-request.

Henrique Cabral

unread,
Aug 13, 2010, 2:54:20 PM8/13/10
to fluent-n...@googlegroups.com
James,

Indeed, but from what I could see during my debug session, referring
to a CSS file is a request, opening an image is another, and so on.
Hence my fictional number of 30 sessions. The methods BeginRequest and
EndRequest are invoked several times.

Cheers,
Henrique

Jason Dentler

unread,
Aug 13, 2010, 3:00:43 PM8/13/10
to fluent-n...@googlegroups.com
Premature optimization. Don't worry about it right now. Sessions are VERY lightweight. Just be sure to dispose of them properly.


On Fri, Aug 13, 2010 at 1:54 PM, Henrique Cabral <hca...@gmail.com> wrote:
James,

Indeed, but from what I could see during my debug session, referring
to a CSS file is a request, opening an image is another, and so on.
Hence my fictional number of 30 sessions. The methods BeginRequest and
EndRequest are invoked several times.

Cheers,
Henrique

James Gregory

unread,
Aug 13, 2010, 3:03:58 PM8/13/10
to fluent-n...@googlegroups.com
You shouldn't be intercepting requests for static resources with asp.net; if you really need to, then you definitely shouldn't be opening sessions for them, that's just crazy.

The only requests that should open sessions are ones that actually request your aspx pages (or controller actions if you're doing mvc).

In a typical web app you'll be looking at opening one session for loading a page; the only exception to that rule is if you're making ajax requests from your page too, in which case each of those would be a new request and therefore a new session.

Nick Webb

unread,
Aug 13, 2010, 3:05:33 PM8/13/10
to fluent-n...@googlegroups.com
Keep in mind those are NHibernate sessions, not database sessions.  NHibernate will only open a connection to the db when necessary.  So the only real cost is of creating an instance of Session in memory.

On Fri, Aug 13, 2010 at 2:54 PM, Henrique Cabral <hca...@gmail.com> wrote:
James,

Indeed, but from what I could see during my debug session, referring
to a CSS file is a request, opening an image is another, and so on.
Hence my fictional number of 30 sessions. The methods BeginRequest and
EndRequest are invoked several times.

Cheers,
Henrique

Henrique Cabral

unread,
Aug 13, 2010, 3:27:26 PM8/13/10
to fluent-n...@googlegroups.com
Will do, thanks. Everything is up and running, I will start several
tests. I can actually feel an improvement already, and by debugging I
confirmed that the mapping is performed only once per DB.

Thank you all for the help, this is a great community!

Cheers,
Henrique Cabral

On Fri, Aug 13, 2010 at 3:00 PM, Jason Dentler <jasond...@gmail.com> wrote:
> Premature optimization. Don't worry about it right now. Sessions are VERY
> lightweight. Just be sure to dispose of them properly.
>
> On Fri, Aug 13, 2010 at 1:54 PM, Henrique Cabral <hca...@gmail.com> wrote:
>>
>> James,
>>
>> Indeed, but from what I could see during my debug session, referring
>> to a CSS file is a request, opening an image is another, and so on.
>> Hence my fictional number of 30 sessions. The methods BeginRequest and
>> EndRequest are invoked several times.
>>
>> Cheers,
>> Henrique
>>

>> On Fri, Aug 13, 2010 at 2:17 PM, James Gregory <jagreg...@gmail.com>

Henrique Cabral

unread,
Aug 13, 2010, 3:47:41 PM8/13/10
to fluent-n...@googlegroups.com
James,

My point exactly, we have some time to study these solutions and fine
tune the application. Even with requests to static objects, like I
mentioned before, there's a significative improvement. I agree with
you, it's crazy, specially if the user base grows. I'm searching on
how to filter the requests.

Nick, and you're right, I also monitored the database connections, I
know I'm dealing with NHiB sessions, not database connections.

Cheers,
Henrique

Reply all
Reply to author
Forward
0 new messages