you can try castle activerecord too, it abstracts a little NH Sesion
artifact
I've looked at this blog post before I posted to this message group,
and it just doesn't make any sense to me. I don't see how to use it in
an actual application scenario. I can't tell if there are multiple
sessions, or just one session for the entire application?
What is a recommended approach to a WinForm application? One session
for the life of the WinForm app?
Or multiple sessions? How long should
a session live?
Who controls when a session is created and when it
dies?
How does that control propagate to repositories or other lower-
level code that actually needs to make use of the session? Or do you
not even worry about abstracting the NHibernate stuff away, and just
use the ISession as a unit of work in the actual application?
> I have yet to see anyone explain this clearly.
Ok, I'll try to give at least some guideline.
First of all: The most important thing to remember is that an ISession
is really unstable and unreliable (according to the book 'Exceptional
C++' of Herb Sutter ISession even breaks the fundamental level of
guarantee). Therefore is should be used only for short periods of time
and be thrown away as fast as possible, because any NHibernate
exception and each rollback immediatley invalidates the session
object.
On the other hand there is lazy loading and this works only as long as
the session is still open. But I think, in many cases it should be
considered bad practise to just load a root entity and rely on
NHibernates lazy loading mechanism to pull all dependent entities into
memory. This pattern is a real performance killer.
IMHO a much better idea is to think of lazy loading as a way of being
able to ignore some data if they don't matter in a given use case. So
for each use case you should always eagerly load all data you will
need and therefore there is no problem in early closing the session.
That's the motivation for all these rather complex patterns like
Session per Business Transaction, Persistence Context, etc.
If you are all new to this, don't try to invent everything from
scratch in your first application. Either use the patterns and
libraries already mentioned or, if you want to really understand and
develop everything yourself, start simple. A rather simple approach
may be to define a service layer (e.g. just a single static class)
that has a public API derived from use cases and only in this layer
ISession objects and a session factory is allowed. Then in each public
method a fresh session is opened, data fetched, maybe some kind of
post-processing/conversion/transformation is done, and before
returning the result the session will be closed. This is the basic
idea of session per business transaction (or per use case).
For applications that are not too complex this might suffice, in more
complex scenarios patterns like the mentioned persistence context
might be needed.
Hope, this helps a little bit.
--
Until the next mail...,
Stefan.
This is incredibly helpful. I had no idea this
capability for contextual sessions existed in NHibernate.
> @Every one who might be interrested : This article deals with a way to
> handle lazy loading in winforms.
> http://www.codeproject.com/KB/cs/NHibernateLazyInitializer.aspx
I don't think this is a good idea, because it may lead to quite bad
performance. A much better approach would be to tailor your HQLs (or
criteria queries) to each use case and select exactly the data you
need to touch explicitly (in many cases this is even possible in one
single HQL, with the help of join fetch and maybe
DistinceRootTransformer, and thus in one single round-trip to the DB,
instead of dozens or even hundreds of round-trips in case of the
generic NNhibernateLazyInitializer).
@Fabio
Even if your articles are very clear and the samples in nhaddins are
very good, reading them was not enough for me to understand them.
And it took me a lots of efforts to understand where is the CpBt in
the samples.