Jeudi le 29 juillet 2010 . 14:59

Gestion des sessions NHibernate

Dimanche, 23 novembre 2008, 16:14
Cet article a été publié dans Développement et a 0 commentaire à ce jour .

La gestion des sessions est un aspect crucial pour tirer avantage de l’utilisation de NHibernate. Le problème vient du fait que la construction du SessionFactory qui gère les transactions et sessions de NHibernate est assez coûteuse. Il existe plusieurs stratégies pour gérer ce problème avec ASP.Net. Dave Byron propose une solution assez simple via un pattern de Unit of Work. Toutefois, cette méthode nécessite également des connaissances des patterns de Depency Injection et de Inversion of Control.

C’est pourquoi celle que je présente ici est exactement celle proposée par Billy McCafferty dans son article NHibernate Best Practices with ASP.Net. La méthode utilise un pattern de Singleton dont l’implantation en C# est présentée sur cette page. Un avantage de cette méthode est qu’elle fonctionnera que vous utilisiez ASP.Net ou bien les WinForms.

using System.Runtime.Remoting.Messaging;
using System.Web;
using NHibernate;
using NHibernate.Cache;
using NHibernate.Cfg;

namespace NHibernateHelper
{
    /// <summary>
    /// Handles creation and management of sessions and transactions.  It is a singleton because
    /// building the initial session factory is very expensive. Inspiration for this class came
    /// from Chapter 8 of Hibernate in Action by Bauer and King.  Although it is a sealed singleton
    /// you can use TypeMock (http://www.typemock.com) for more flexible testing.
    /// </summary>
    public sealed class NHibernateSessionManager
    {
        #region Thread-safe, lazy Singleton

        /// <summary>
        /// This is a thread-safe, lazy singleton.  See http://www.yoda.arachsys.com/csharp/singleton.html
        /// for more details about its implementation.
        /// </summary>
        public static NHibernateSessionManager Instance {
            get {
                return Nested.NHibernateSessionManager;
            }
        }

        /// <summary>
        /// Initializes the NHibernate session factory upon instantiation.
        /// </summary>
        private NHibernateSessionManager() {
            InitSessionFactory();
        }

        /// <summary>
        /// Assists with ensuring thread-safe, lazy singleton
        /// </summary>
        private class Nested
        {
            static Nested() { }
            internal static readonly NHibernateSessionManager NHibernateSessionManager =
                new NHibernateSessionManager();
        }

        #endregion

        private void InitSessionFactory() {
            sessionFactory = new Configuration().Configure().BuildSessionFactory();
        }

        /// <summary>
        /// Allows you to register an interceptor on a new session.  This may not be called if there is already
        /// an open session attached to the HttpContext.  If you have an interceptor to be used, modify
        /// the HttpModule to call this before calling BeginTransaction().
        /// </summary>
        public void RegisterInterceptor(IInterceptor interceptor) {
            ISession session = ContextSession;

                if (session != null && session.IsOpen) {
                throw new CacheException("You cannot register an interceptor once a session has already been opened");
            }

            GetSession(interceptor);
        }

        public ISession GetSession() {
            return GetSession(null);
        }

        /// <summary>
        /// Gets a session with or without an interceptor.  This method is not called directly; instead,
        /// it gets invoked from other public methods.
        /// </summary>
        private ISession GetSession(IInterceptor interceptor) {
            ISession session = ContextSession;

            if (session == null) {
                if (interceptor != null) {
                    session = sessionFactory.OpenSession(interceptor);
                }
                else {
                    session = sessionFactory.OpenSession();
                }

                ContextSession = session;
            }

            return session;
        }

        /// <summary>
        /// Flushes anything left in the session and closes the connection.
        /// </summary>
        public void CloseSession() {
            ISession session = ContextSession;

            if (session != null && session.IsOpen) {
                session.Flush();
                session.Close();
            }

            ContextSession = null;
        }

        public void BeginTransaction() {
            ITransaction transaction = ContextTransaction;

            if (transaction == null) {
                transaction = GetSession().BeginTransaction();
                ContextTransaction = transaction;
            }
        }

        public void CommitTransaction() {
            ITransaction transaction = ContextTransaction;

            try {
                if (HasOpenTransaction()) {
                    transaction.Commit();
                    ContextTransaction = null;
                }
            }
            catch (HibernateException) {
                RollbackTransaction();
                throw;
            }
        }

        public bool HasOpenTransaction() {
            ITransaction transaction = ContextTransaction;

            return transaction != null && !transaction.WasCommitted && !transaction.WasRolledBack;
        }

        public void RollbackTransaction() {
            ITransaction transaction = ContextTransaction;

            try {
                if (HasOpenTransaction()) {
                    transaction.Rollback();
                }

                ContextTransaction = null;
            }
            finally {
                CloseSession();
            }
        }

        /// <summary>
        /// If within a web context, this uses <see cref="HttpContext" /> instead of the WinForms
        /// specific <see cref="CallContext" />.  Discussion concerning this found at
        /// http://forum.springframework.net/showthread.php?t=572.
        /// </summary>
        private ITransaction ContextTransaction {
            get {
                if (IsInWebContext()) {
                    return (ITransaction)HttpContext.Current.Items[TRANSACTION_KEY];
                }
                else {
                    return (ITransaction)CallContext.GetData(TRANSACTION_KEY);
                }
            }
            set {
                if (IsInWebContext()) {
                    HttpContext.Current.Items[TRANSACTION_KEY] = value;
                }
                else {
                    CallContext.SetData(TRANSACTION_KEY, value);
                }
            }
        }

        /// <summary>
        /// If within a web context, this uses <see cref="HttpContext" /> instead of the WinForms
        /// specific <see cref="CallContext" />.  Discussion concerning this found at
        /// http://forum.springframework.net/showthread.php?t=572.
        /// </summary>
        private ISession ContextSession {
            get {
                if (IsInWebContext()) {
                    return (ISession)HttpContext.Current.Items[SESSION_KEY];
                }
                else {
                    return (ISession)CallContext.GetData(SESSION_KEY);
                }
            }
            set {
                if (IsInWebContext()) {
                    HttpContext.Current.Items[SESSION_KEY] = value;
                }
                else {
                    CallContext.SetData(SESSION_KEY, value);
                }
            }
        }

        private bool IsInWebContext() {
            return HttpContext.Current != null;
        }

        private const string TRANSACTION_KEY = "nhibernate.context.transaction.key";
        private const string SESSION_KEY = "nhibernate.context.session.key";
        private ISessionFactory sessionFactory;
    }
}

Un petite note: peu importe la méthode utilisée, si vous êtes dans un contexte Web, il faut généralement s’assurer que la méthode est Thread-Safe.

Une question demeure toutefois, quand doit-on créer les sessions et transactions et quand doit-on les fermer? La documentation suggère de mettre en oeuvre le pattern Open-In-Session-View afin de mettre à profit les possiblités de lazy-loading de NHibernate. Billy McCafferty mentionnait dans son article:

If you want to leverage NHibernate’s lazy-loading (which you most certainly will), then the Open-Session-in-View pattern is the way to go. (”Session” in this context is the NHibernate ISession…not the ASP.NET Session object.) Essentially, this pattern suggests that one NHibernate session be opened per HTTP request.

Encore une fois, l’approche proposée est celle que je présente. Le pattern signifie qu’une session NHibernate doit être ouverte par requête HTTP. En asp.net, le plus simple pour accomplir cette tâche à mon avis est en effet de créer un IHttpModule. On crée la session au début de la requête et on la ferme à la fin. S’il y a des changements à effectués, ils seront engagés avant la fermeture de la session. S’il y a des erreurs, la transaction sera annulée et la session sera quand même fermée. Voici le code du module qui se veut assez simple.

using System;
using System.Web;

namespace NHibernateHelper.Modules
{
    /// <summary>
    /// Implements the Open-Session-In-View pattern using <see cref="NHibernateSessionManager" />.
    /// Assumes that each HTTP request is given a single transaction for the entire page-lifecycle.
    /// Inspiration for this class came from Ed Courtenay at
    /// http://sourceforge.net/forum/message.php?msg_id=2847509.
    /// </summary>
    public class NHibernateSessionModule : IHttpModule
    {
        public void Init(HttpApplication context) {
            context.BeginRequest += new EventHandler(BeginTransaction);
            context.EndRequest += new EventHandler(CommitAndCloseSession);
        }

        /// <summary>
        /// Opens a session within a transaction at the beginning of the HTTP request.
        /// This doesn't actually open a connection to the database until needed.
        /// </summary>
        private void BeginTransaction(object sender, EventArgs e) {
            NHibernateSessionManager.Instance.BeginTransaction();
        }

        /// <summary>
        /// Commits and closes the NHibernate session provided by the supplied <see cref="NHibernateSessionManager"/>.
        /// Assumes a transaction was begun at the beginning of the request; but a transaction or session does
        /// not *have* to be opened for this to operate successfully.
        /// </summary>
        private void CommitAndCloseSession(object sender, EventArgs e) {
            try {
                NHibernateSessionManager.Instance.CommitTransaction();
            }
            finally {
                NHibernateSessionManager.Instance.CloseSession();
            }
        }

        public void Dispose() { }
    }
}

Voilà, il ne vous reste plus qu’à configurer le module http dans votre web.config et vous serez en mesure de gérer vos sessions NHibernate sans trop de problèmes.

Finalement, un simple exemple pour exécuter une requête via notre gestionnaire de session:

...
ISession session = NHibernateSessionManager.Instance.GetSession();
return session.Get<T>(id);
Vous pouvez passer à la fin et laisser une réponse. Les pings ne sont actuellement pas autorisés.

Commenter sur “Gestion des sessions NHibernate”

Laisser un commentaire

cheapest price for viagra and cialis
cheapest viagra in uk che
discount cialis
buy online prescription viagra without
buy viagra in new zealand
buy viagra onli
buy viagra with paypal
cheap Microsoft Math
adobe discount
buy flomax
cheap viagra 25mg
cheapest 4 quantity of viagra
cialis 5
buy discount soma
over sea generic viagra
discount viagra 10 pack generic
amd 64 barebones
cube barebones
cheap drugs viagra cialas
cheap generic viagra from usa
cheap cialis online
order viagra on line
cheap deal pill pill viagra
buy uk viagra
order viagra overnight shipping
adobe acrobat discount
discount viagra brand drug
buy cheap viagra uk
viagra buy online
buy viagra from brazil
buy computer systems
buy generic viagra online pharmacy online
buy viagra all information
order viagra prescription
buy hgh now
cheap sale viagra
cheaper viagra levitra apcalis
levitra online
cheap discount soma
purchase soma
cheapest viagra on line
cheapest generic viagra 99 cents each
cheap deal discount price viagra
ddr3 barebones
buy 100 mg viagra
buy viagra per pill
free ringtone download
buy viagra now online
buy diflucan
buy cheap discount paxil
cheap drug viagra
game system
buy viagra bradenton
viagra buying online
wicked game ringtone for sprint
cheap generic overnight viagra
buy cheap online uk viagra
buy discount zoloft
buy soma now
cheap viagra in the uk
seroquel
buy p viagra
order paxil online
polyphonic ringtone composer
cheap herbal viagra viagra
buy viagra without prescription pharmacy online
buy photoshop elements 6
cheap online softtabs viagra
cheap viagra discount viagra buy viagra
buy cheap discount levitra
i5 barebones
buy levitra viagra online
buy cheap viagra in uk
cheapest price on viagra
msi barebones
cheap generic viagra overnight delivery
viagra and cialis cheap
viagra and diabetes
where can i get a free nokia ringtone
athlon barebones
buy viagra uk
cheapest generic viagra
buy viagra vaniqa prescription
adobe cs3 premium production student discount
buy drug generic generic online viagra
buy generic viagra pharmacy online
buy viagra and cilas
buy low price viagra
buy depakote
cheap gerneric viagra
cheap viagra india
computer store
cheap viagra direct
buy viagra online india
cheap viagra at online pharmacy
buy generic viagra buy
discount viagra sales online
order cheap viagra fas
discount adobe contribute
buy viagra cheapest
buy viagra woman
buy nolvadex
ddr2 barebones
buy citrate generic sildenafil viagra
order viagra online
buy cheap discount crestor
bild ...
cheap lexapro
buy cheap viagra cheap viagra online
buy discount viagra viagra viagra
buy legal fda approved viagra
cheap genric viagra online
buy viagra online a href
buy cheap free online viagra viagra
cheap man viagra
buy real viagra
order cheap viagra
buy no online prescription viagra
cheap inexpensive viagra
order viagra air travel
order viagra with mastercard
buy viagra no prescription
buy buy sale viagra viagra
viagra buy uk
buy online online pill viagra viagra
viagra by mail
buy pfizer viagra
viagra by mail catalog
viagra buy viagra online
cheep generic viagra
cheap herbal viagra
buy viagra with discount
gaming ...
ringtone farm
cheap online price price viagra
cheap viagra st
buy female viagra
cheap herbal sale viagra viagra
discount viagra sales
buy viagra online canada
buy viagra online in uk
cheap levitra online
buy cialis online viagra
buy online viagra where
buy purchase viagra online confidential
cheaper viagra levitra cyalis
buy cheap discount soma
free polyphonic ringtone
buy viagra online at lowest price
viagra and fertility
cheap viagra uks
buy caverta
cheapest viagra generic substitute
order viagra 1
buy softtabs viagra
order viagra softtabs
cheap online sales viagra
buy cheap sale viagra
cheapest price viagra
order viagra overnight delivery
discount viagra mastercard
discount viagra offers
cheap crestor
buy online price viagra
ringtone ripper
cheapest viagra on the internet
buy viagra viagra online
adobe discount codes coupons
cheap mexico viagra
cheap drug retin viagra wellbutrin
buy viagra online u
free ringtone creator
cheapest viagra in uk
cheapest viagra tablets
buy taladafil viagra
buy form generic viagra
buy viagra inte
cheapest generic price viagra
cheap phizer viagra
buy online us viagra
buy say viagra
generic cialis
cialis 24
buy viagra without a perscription
discount viagra prescription drug
buy soma canada
cialis 50mg
order crestor online
buy online uk viagra
order viagra now
cheapest viagra prices us licensed pharmacies
buy buying sale viagra
cheap testosterone viagra href foro
ringtone creator
cheapest viagra cheapest generic viagra home
discount viagra pharmacy online
cheap herbal viagra viagra viagra
cheap pill pill sale viagra
msi barebones
cialis 10
order levitra
cheap deal viagra
cheap generic viagra
buy viagra or cilas
cheap viagra no prescription
buy discount generic viagra
buy discount viagra
cheapest viagra online
free mobile ringtone downloads
mosquito ringtone download
buy lexapro
buy n viagra
buy viagra where
viagra buy general
boomer sooner ringtone
buy prescription vaniqa viagra
lexapro side effects
viagra and fda
buy generic viagra img
buy soma online
buy online viagra in the uk
purchase levitra
buy online pill viagra
buy discount online viagra
buy viagra online at cheap price
discount crestor
cheap levitra
crank ringtone
buy viagra online and get prescription
zoloft online
xp
cheap levitra viagra href foro forum
cheap viagra discount
buy Photoshop Elements
cheap viagra online uk
buy viagra in toronto
order viagra online in wisconsin
cheapest price for generic viagra
discount adobe lightroom
buy herbal viagra
buy real viagra online
buy cheap uk viagra
viagra by money order
buy cheap discount pill viagra viagra
cheap discount soma online
cellphone ringtone
viagra and cialis side effects
cheap viagra buy pharmacy online now
buy online order viagra
order cialis and viagra
order generic viagra
order viagra international ships
cheap viagra index
buy viagra over the counter
viagra buy generic
cheap order prescription viagra
motorola ringtone composer
bare bone workstation
imperial march ringtone
cheap cheap viagra viagra
cheap cheap herbal viagra viagra viagra
50 cent ringtone
buy free viagra viagra
cheapest viagra in uk cheap
cheap viagra from pfizer
polyphonic ringtone
buy viagra online in the uk
buy viagra generic
buy soft generic viagra cheapest
discount viagra generic
cheap price viagra
cheap viagra kamagra
cheap viagra generic paypal
nokia old fashioned telephone ringtone
buy diet viagra online
buy viagra in spain
buy viagra line
order order viagra
buy generic viagra online
the godfather ringtone
ghost ringtone
cheap cialis viagra
buy viagra on line uk
buy viagra online order generic viagra
viagra and deafness
buy cialis online
order viagra now viagra money order
buy online sale viagra viagra
buy cheap viagra online uk
cheapest viagra online plus zenegra
buy cheap viagra online now uk
buy viagra over the counter us
Adobe Soundbooth oem
buy viagra buy cheap viagra index
cheep viagra from indea
inxs what you need ringtone
cheap pharmacy viagra
buy online levitra cialis viagra
buy cheapest online place viagra
cheapest viagra substitut
viagra buy contest
buy in online usa viagra
viagra and cialas
cheapest prices for viagra online
Photoshop Elements oem
cheap viagra online pharmacy online
buy viagra in london
cheap generic viagra substitutes
buy avandia
buy viagra ups
customize computer system
phone prepaid wireless ringtone
buy online viagra securely buy phentermine
order viagra cialis levitra pharmacy
built barebone system
buy cialis viagra
cheap drug generic generic viagra
buy viagra online 350
buy sublingual viagra online
buy real viagra online pharmacy
cheap testosterone viagra href foro forum
buy get online prescription viagra
buy viagra $8 per pill
viagra and flomax
cheapest generic viagra and canada
cheapest uk supplier viagra
viagra and hearing loss
buy deal herbal viagra viagra
cheap viagra without a pr
buy viagra 32
free mp3 to ringtone converter
order 50mg viagra
cheaper viagra levitra cialis
cheap discount lexapro
order viagra usa
shut up ringtone
sanyo ringtone download
buy viagra in uk
discount viagra drug
buy cialis
randy orton ringtone
buy viagra safeway pharmacy
buy viagra online 35008
buy followup post viagra
buy levitra online
free ringtone downloads
cialis 2005
cheapest in uk viagra
viagra buy it online now
buy viagra cheapest best prices online
viagra buy now pay later
cheapest prices on generic viagra
cheap online order viagra
viagra and generic drug
buy crestor
buy Adobe GoLive
buy cheao cgeap kamagra uk viagra
over the counter viagra alternatives
buy paxil canada
buy cheap viagra viagra
cheep viagra 600mg uk
order viagra
cheapest generic silagra viagra
buy discount levitra
cheap generic viagra online
buy line viagra
purchase barebone pc
cheap drug online prescription viagra
buy adobe photoshop elements 6
buy claritin
buy viagra
buy viagra ebay
buy viagra and overseas
cheap viagra
buy viagra cheap india pharmacy
buy cheap online prescription viagra
cheapest viagra substitute sildenafil
buy later now pay viagra
buy viagra cheaply
flint phone ringtone
download ringtone
buy viagra alternative
cheap uk viagra
buy viagra in england
buy cheap viagra 32
buy viagra for cheap
discount viagra pills
viagra buy ionline
over the counter viagra substitute
buy fosamax
buy viagra cheap prices
discount levitra
buy viagra new york
cheap viagra online a href
cialis 10mg
cheaper cialis levitra viagra
cheapest place to buy viagra
buy viagra in amsterdam
buy cymbalta
buy australian viagra
make ringtone
buy viagra in united kingdom
buy discount cialis
free ringtone converter
buy viagra in great britain
order zoloft
buy herbal pill viagra viagra
buy viagra without a prescription
buy Adobe Encore
order site viagra
buy evista
cheapest prescription viagra
viagra by mail canada
buy viagra online paypal vipps
buy viagra online 35008 buy
adobe photoshop elements 7.0 discounts
viagra buy
buy lipitor
buy cheap online viagra viagra
cheap paxil online
buy viagra cialis levitra
Adobe Premiere oem
order viagra canada
cheap Adobe Premiere
order mexican viagra
buy cheap generic viagra online
cheap soma online
buy hgh canada
buy deal deal price viagra
buy kamagra viagra india
buy pill price price viagra
buy lasix
buy viagra and cilas usa
order prescription viagra
cheap pill viagra
buy canada in viagra
cheap generic viagra no prescription
buy discount crestor
cheap generic online viagra
cheap viagra generic
buy locally viagra
computer configurator
discount viagra order viagra discount viagra
buy viagra free on internet
order generic viagra online
buy norvasc
buy coumadin
adobe acrobat 8 standard discount
cheap discount levitra
ddr2 barebones
cheapest generic viagra 99 cents
buy viagra online in australia
buy line viagra where
free us cellular ringtone downloads
intel barebones
mp3 to ringtone
cheap discount cialis online
mosquito ringtone
cheap viagra online prescription
buy buy cheap viagra
buy viagra us pharmacy low prices
buy cheap crestor
buy discounted viagra
cheapest viagra uk
custom media systems
check generic order pay viagra
cheap generic india viagra
buy viagra online uk
discount viagra
ringtone
buy cheap purchase uk viagra
cheap websites for viagra
cheap order site viagra
free nokia ringtone
buy generic online viagra
discount viagra overseas
cheap viagra cialis india
buy viagra online now buy viagra
buy viagra 1
buy levitra now
buy viagra assist cheap cialis
buy viagra australia
buy viagra other drug online
cheap meltabs online viagra
cheap kamagra viagra
buy now cialis
buy cheap cheap kamagra uk viagra
built online computer system
atx barebones
cheap Cakewalk Guitar Studio
viagra buy australia
buy celebrex
cheap viagra new zealand
cheap viagra nz
order cialis online
cialis 1
viagra and discovery
cheap generic viagra substitute
buy viagra online cheapest
buy cheap viagra