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.  [ 5 posts ] 
Author Message
 Post subject: Managing session using Session Per Conversation pattern.
PostPosted: Fri Nov 16, 2007 5:52 am 
Newbie

Joined: Wed Dec 13, 2006 10:34 am
Posts: 4
Hi

I have a long running wizard form for which I need to keep the Hibernate Session open. I read the below article explaining how to maintain session for multiple conversation in Java - http://hibernate.org/43.html

Is there an example for the same in ASP.NET?

Let me know.

Thanks
Kaushik


Top
 Profile  
 
 Post subject:
PostPosted: Fri Nov 16, 2007 8:07 am 
Newbie

Joined: Wed Jul 11, 2007 9:35 am
Posts: 4
Hi Kaushik

In ASP.NET you implement this pattern through a Session module.

Create a class implementing IHttpModule:

Code:
public class NHibernateSessionModule : IHttpModule
    {
        public void Init(HttpApplication context)
        {
            context.BeginRequest += new EventHandler(BeginTransaction);
            context.EndRequest += new EventHandler(EndTransaction);
        }

private void BeginTransaction(object sender, EventArgs e)
        {

        }
private void EndTransaction(object sender, EventArgs e)
        {
        }
}


Implement your reconnection in the BeginTransaction.

Finaly, Load the module in your web.config:
Code:
<system.web>
<httpModules>
         <add name="NHibernateSessionModule" type="NHibernateSessionModule, <Assembly>"/>
</httpModules>
</system.web>


Hope this helps.

Sérgio


Top
 Profile  
 
 Post subject: Managing session using Session Per Conversation pattern.
PostPosted: Mon Nov 19, 2007 9:11 am 
Newbie

Joined: Wed Dec 13, 2006 10:34 am
Posts: 4
Hi

Thanks, for your reply.

Could you tell me what would be the equivalent of Binding the Session in Nhibernate?

In Java the following is used -
Code:
//Binding the current Session
ManagedSessionContext.bind(currentSession);


Ref - http://hibernate.org/43.html

Please let me know.

Thanks
Kaushik


Top
 Profile  
 
 Post subject: Managing session using Session Per Conversation pattern.
PostPosted: Mon Nov 19, 2007 9:37 am 
Newbie

Joined: Wed Dec 13, 2006 10:34 am
Posts: 4
Hi

Below is the code I am using. After the session is opened or read from the HttpSessionState, How do I bind the session on the currrent thread?

Code:
public class HibernateSessionConversationFilter : OpenSessionInViewModule, IHttpModule
{
    /// <summary>
    /// Initializes a new instance of the <see cref="T:HibernateSessionConversationFilter"/> class.
    /// </summary>
    public HibernateSessionConversationFilter() : base("appSettings", false)
    {
    }

    ///<summary>
    ///Initializes a module and prepares it to handle requests.
    ///</summary>
    ///
    ///<param name="context">An <see cref="T:System.Web.HttpApplication"></see> that provides access to the methods, properties, and events common to all application objects within an ASP.NET application </param>
    public void Init(HttpApplication context)
    {
        context.PreRequestHandlerExecute += new EventHandler(context_PreRequestHandlerExecute);
        context.PostRequestHandlerExecute += new EventHandler(context_PostRequestHandlerExecute);
    }

    void context_PreRequestHandlerExecute(object sender, EventArgs e)
    {
        // Try to get a Hibernate Session from the HttpSession
        ISession disconnectedSession = HttpContext.Current.Session["HIBERNATE_SESSION_KEY"] as ISession;

        try
        {
            // Start a new conversation or in the middle?
            if (disconnectedSession == null)
            {
                Log.Write(">>> New conversation");
                base.Open();
                currentSession = base.SessionFactory.OpenSession();
            }
            else
            {
                Log.Write("< Continuing conversation");
                currentSession = disconnectedSession;
            }

            //HOW TO BIND THE SESSION
            //ManagedSessionContext.bind(currentSession);

            CacheHibernateSession("HIBERNATE_SESSION_KEY", currentSession);
        }
        catch (StaleObjectStateException staleEx)
        {
            throw staleEx;
        }
        catch (Exception ex)
        {
           throw ex;
        }
    }

    void context_PostRequestHandlerExecute(object sender, EventArgs e)
    {
        // Try to get a Hibernate Session from the HttpSession
        ISession currentSession = HttpContext.Current.Session["HIBERNATE_SESSION_KEY"] as ISession;

        try
        {
            // End or continue the long-running conversation?
            if (null != HttpContext.Current.Session["END_OF_CONVERSATION_FLAG"] &&
                true != Convert.ToBoolean(HttpContext.Current.Session["END_OF_CONVERSATION_FLAG"]))
            {
                base.Close();

                Log.Write("Cleaning Session from HttpSession");
                RemoveHibernateSessionFromCache("HIBERNATE_SESSION_KEY");
                Log.Write("<<< End of conversation");
            }
            else
            {
                Log.Write("Committing database transaction");

                if (currentSession.Transaction.IsActive)
                {
                    currentSession.Transaction.Commit();
                }

                Log.Write("Storing Session in the HttpSession");
                CacheHibernateSession("HIBERNATE_SESSION_KEY", currentSession);
                Log.Write("> Returning to user in conversation");
            }
        }
        catch (StaleObjectStateException staleEx)
        {
            throw staleEx;
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

    private void CacheHibernateSession(string key, object value)
    {
        if (null != HttpContext.Current.Session[key])
        {
            HttpContext.Current.Session[key] = value;
        }
        else
        {
            HttpContext.Current.Session.Add(key, value);
        }
    }

    private void RemoveHibernateSessionFromCache(string key)
    {
        if (null != HttpContext.Current.Session[key])
        {
            HttpContext.Current.Session.Remove(key);
        }
    }
}



Thanks
Kaushik


Top
 Profile  
 
 Post subject:
PostPosted: Tue Nov 20, 2007 6:57 am 
Contributor
Contributor

Joined: Sun Jun 26, 2005 5:03 am
Posts: 51
Location: London, UK
You can't easily keep a Session open over multiple pages in ASP.NET due to the stateless nature of the web; it's also not a good idea for scalability/threading reasons.

Couple of suggestions...

1. Persist your domain object state after each page in your wizard.
2. Store your domain object in the ASP.NET session state

I prefer the first choice as it's the most scalable (e.g. it will play nice with web farms), but you can put the domain object into the ASP.NET session state and re-attach it when required.

_________________
Paul Hatcher
NHibernate Team


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