I´ve got the following code for manage Nhiberante Session. My problem is that sometimes changes takes more time to persist. That is i make a change in the db and another user cannot see the change maybe till 2 hours laters. What can be the problem? SOmebody told that is because i don´t commit the changes/roollback but this is false because i do that allways. What can be worng?
using System;
using System.Web;
using System.Web.SessionState;
//using System.Web.SessionState.HttpSessionState;
using System.Runtime.Remoting.Messaging;
using NHibernate;
using NHibernate.Cfg;
namespace .utils.nhibernate
{
/// <summary>
/// Summary description for NHibernateHttpModule.
/// </summary>
public class NHibernateHttpModule : IHttpModule,IRequiresSessionState
{
// this is only used if not running in HttpModule mode
protected static ISessionFactory m_factory;
// this is only used if not running in HttpModule mode
private static ISession m_session;
private static readonly string KEY_NHIBERNATE_FACTORY = "NHibernateSessionFactory";
private static readonly string KEY_NHIBERNATE_SESSION = "NHibernateSession";
private const string TRANSACTION_KEY = "CONTEXT_TRANSACTION";
public void Init(HttpApplication context)
{
log4net.Config.XmlConfigurator.Configure();
/* context.
System.Globalization.DateTimeFormatInfo dateTimeInfo = new System.Globalization.DateTimeFormatInfo();
dateTimeInfo.*/
/*context.BeginRequest += new EventHandler(context_BeginRequest);
context.EndRequest += new EventHandler(context_EndRequest);*/
context.PreRequestHandlerExecute += new EventHandler(context_PreRequest);
context.PostRequestHandlerExecute += new EventHandler(context_PostRequest);
}
public void Dispose()
{
if (m_session != null)
{
m_session.Close();
m_session.Dispose();
}
if (m_factory != null)
{
m_factory.Close();
}
}
private void context_PreRequest(object sender, EventArgs e)
{
HttpApplication application = (HttpApplication)sender;
HttpContext context = application.Context;
HttpApplication app = (System.Web.HttpApplication)sender;
HttpSessionState o = app.Context.Session;
if (o!=null && o["sesionBdD"] != null)
{
if (!((ISession)o["sesionBdD"]).IsConnected)
((ISession)o["sesionBdD"]).Reconnect();
context.Items[KEY_NHIBERNATE_SESSION] = ((ISession)o["sesionBdD"]);
}
else
{
context.Items[KEY_NHIBERNATE_SESSION] = CreateSession();
if (o !=null)
o.Add("sesionBdD",context.Items[KEY_NHIBERNATE_SESSION]);
}
}
private void context_PostRequest(object sender, EventArgs e)
{
HttpApplication application = (HttpApplication)sender;
HttpContext context = application.Context;
ISession session = context.Items[KEY_NHIBERNATE_SESSION] as ISession;
if (session != null)
{
try
{
// session.Flush();
session.Disconnect();
// HttpSessionState o = context.Session;
// o["sesionBdD"] = session;
//session.Flush();
//session.Close();
}
catch (Exception ex) { session.Close(); }
}
}
private void context_BeginRequest(object sender, EventArgs e)
{
HttpApplication application = (HttpApplication)sender;
HttpContext context = application.Context;
HttpApplication app = (System.Web.HttpApplication)sender;
// HttpSessionState o = app.Context.Session;
/* if (o!=null && o["sesionBdD"] != null)
{
((ISession)o["sesionBdD"]).Reconnect();
context.Items[KEY_NHIBERNATE_SESSION] = ((ISession)o["sesionBdD"]);
}
else
{*/
context.Items[KEY_NHIBERNATE_SESSION] = CreateSession();
/*}*/
}
private void Close(HttpApplication application)
{
HttpContext context = application.Context;
ISession session = context.Items[KEY_NHIBERNATE_SESSION] as ISession;
if (session != null)
{
try
{
session.Flush();
session.Close();
HttpSessionState o = application.Context.Session;
if (o["sesionBdD"] != null)
{
o.Remove("sesionBdD");
}
}
catch (Exception ex) { session.Close(); }
}
// context.Items[KEY_NHIBERNATE_SESSION] = null;
}
private void context_EndRequest(object sender, EventArgs e)
{
HttpApplication application = (HttpApplication)sender;
HttpContext context = application.Context;
ISession session = context.Items[KEY_NHIBERNATE_SESSION] as ISession;
if (session != null)
{
try
{
// session.Flush();
session.Disconnect();
HttpSessionState o = context.Session;
// o["sesionBdD"] = session;
session.Flush();
session.Close();
}
catch (Exception ex) { session.Close(); }
}
// context.Items[KEY_NHIBERNATE_SESSION] = null;
}
protected static ISessionFactory CreateSessionFactory()
{
Configuration config;
ISessionFactory factory = null;
config = new Configuration();
try
{
if (config == null)
{
throw new InvalidOperationException("NHibernate configuration is null.");
}
//config = config.Configure("hibernate.cfg.xml");
config.Configure();
factory = config.BuildSessionFactory();
foreach (NHibernate.Mapping.PersistentClass pClass in config.ClassMappings)
{
string schema = System.Configuration.ConfigurationManager.AppSettings[pClass.MappedClass.Assembly.ManifestModule.Name];
if (schema != null) //cambiamos el schema de la Base de datos si no se queda tal cual
pClass.RootTable.Schema = schema;
}
if (factory == null)
{
throw new InvalidOperationException("Call to Configuration.BuildSessionFactory() returned null.");
}
else
{
return factory;
}
}
catch (Exception e)
{
foreach (NHibernate.Mapping.PersistentClass pClass in config.ClassMappings)
{
string schema = System.Configuration.ConfigurationManager.AppSettings[pClass.MappedClass.Assembly.ManifestModule.Name];
if (schema != null) //cambiamos el schema de la Base de datos si no se queda tal cual
pClass.RootTable.Schema = schema;
}
factory = config.BuildSessionFactory();
if (factory == null)
{
throw new InvalidOperationException("Call to Configuration.BuildSessionFactory() returned null.");
}
else
{
return factory;
}
}
}
public static ISessionFactory CurrentFactory
{
get
{
if (HttpContext.Current == null)
{
// running without an HttpContext (non-web mode)
// the nhibernate session is a singleton in the app domain
if (m_factory != null)
{
return m_factory;
}
else
{
m_factory = CreateSessionFactory();
return m_factory;
}
}
else
{
// running inside of an HttpContext (web mode)
// the nhibernate session is a singleton to the http request
HttpContext currentContext = HttpContext.Current;
ISessionFactory factory = currentContext.Application[KEY_NHIBERNATE_FACTORY] as ISessionFactory;
if (factory == null)
{
factory = CreateSessionFactory();
currentContext.Application[KEY_NHIBERNATE_FACTORY] = factory;
}
return factory;
}
}
}
public static ISession CreateSession()
{
ISessionFactory factory;
ISession session;
factory = NHibernateHttpModule.CurrentFactory;
if (factory == null)
{
throw new InvalidOperationException("Call to Configuration.BuildSessionFactory() returned null.");
}
session = factory.OpenSession();
if (session == null)
{
throw new InvalidOperationException("Call to factory.OpenSession() returned null.");
}
return session;
}
public static ISession CurrentSession
{
get
{
if (HttpContext.Current == null)
{
// running without an HttpContext (non-web mode)
// the nhibernate session is a singleton in the app domain
if (m_session != null)
{
return m_session;
}
else
{
m_session = CreateSession();
return m_session;
}
}
else
{
// running inside of an HttpContext (web mode)
// the nhibernate session is a singleton to the http request
HttpContext currentContext = HttpContext.Current;
ISession session = currentContext.Items[KEY_NHIBERNATE_SESSION] as ISession;
if (session == null)
{
session = CreateSession();
currentContext.Items[KEY_NHIBERNATE_SESSION] = session;
}
return session;
}
}
}
public void BeginTransaction()
{
ITransaction transaction = ContextTransaction;
if (transaction == null)
{
transaction = CurrentSession.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;
}catch(Exception e){
}
}
/// <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);
}
}
}
private bool IsInWebContext()
{
return HttpContext.Current != null;
}
public static void CaducarSesion()
{
if (m_session!=null)
m_session.Clear(); //se limpian los datos de la sesión
}
}
}