View Full Version : OpenSessionInViewFilter
Abadio
03-27-2006, 07:15 PM
I am using the spring Nhibernate Dao suport, but I need the lazy load inicialization. I´d like to know if there is implemented OpenSessionInViewFilter like in Java. I look for sorurce directory in sandbox, but I didn´t find it.
this is sample code
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using NHibernate;
using Spring.Context.Support;
using Spring.Transaction.Support;
using log4net;
namespace Spring.Data.Orm.NHibernate.Support
{
public class OpenSessionInViewModule : IHttpModule
{
protected static ILog logger = LogManager.GetLogger(typeof(OpenSessionInViewModul e));
public const String DEFAULT_SESSION_FACTORY_OBJECT_NAME = "sessionFactory";
private String sessionFactoryObjectName = DEFAULT_SESSION_FACTORY_OBJECT_NAME;
private bool singleSession = true;
private ISessionFactory sessionFactory=null;
private bool participate = false;
private ISession session = null;
/// <summary>
/// Set or return the object name of the SessionFactory to fetch from Spring's
/// root application context. Default is "sessionFactory".
/// </summary>
public String SessionFactoryObjectName{
set { sessionFactoryObjectName = value; }
get { return sessionFactoryObjectName; }
}
///<summary>
/// Set whether to use a single session for each request. Default is "true".
///
If set to false, each data access operation or transaction will use
///its own session (like without Open Session in View). Each of those
///sessions will be registered for deferred close, though, actually
/// processed at request completion.
public bool SingleSession
{
set { singleSession = value; }
get { return singleSession; }
}
public void Dispose()
{
}
public void Init(HttpApplication context)
{
//获取默认配置
String fullName = GetType().FullName;
String s1 = System.Configuration.ConfigurationSettings.AppSett ings[fullName+"SessionFactoryObjectName"];
String s2=System.Configuration.ConfigurationSettings.AppS ettings[fullName+"SingleSession"];
if (!String.IsNullOrEmpty(s1))
SessionFactoryObjectName = s1;
if (!String.IsNullOrEmpty(s2))
SingleSession=bool.Parse(s2);
context.BeginRequest += new EventHandler(context_BeginRequest);
context.EndRequest += new EventHandler(context_EndRequest);
}
void context_EndRequest(object sender, EventArgs e)
{
if (!participate)
{
if (SingleSession)
{
// single session mode
TransactionSynchronizationManager.UnbindResource(s essionFactory);
logger.Debug("Closing single Hibernate Session in OpenSessionInViewFilter");
try
{
CloseSession(session, sessionFactory);
}
catch (Exception ex)
{
logger.Error("Unexpected exception on closing Hibernate Session", ex);
}
}
else
{
// deferred close mode
SessionFactoryUtils.ProcessDeferredClose(sessionFa ctory);
}
}
}
void context_BeginRequest(object sender, EventArgs e)
{
sessionFactory = (ISessionFactory)ContextRegistry.GetContext().GetO bject(SessionFactoryObjectName);
if (SingleSession)
{
// single session mode
if (TransactionSynchronizationManager.HasResource(ses sionFactory))
{
// Do not modify the Session: just set the participate flag.
participate = true;
}
else
{
logger.Debug("Opening single Hibernate Session in OpenSessionInViewFilter");
session = GetSession(sessionFactory);
TransactionSynchronizationManager.BindResource(ses sionFactory, new SessionHolder(session));
}
}
else
{
// deferred close mode
if (SessionFactoryUtils.IsDeferredCloseActive(session Factory))
{
// Do not modify deferred close: just set the participate flag.
participate = true;
}
else
{
SessionFactoryUtils.InitDeferredClose(sessionFacto ry);
}
}
}
/// <summary>
///
/// </summary>
/// <param name="sessionFactory"></param>
/// <returns></returns>
protected virtual ISession GetSession(ISessionFactory sessionFactory) {
return OpenSession(sessionFactory);
}
/// <summary>
///
/// </summary>
/// <param name="sessionFactory"></param>
/// <returns></returns>
protected virtual ISession OpenSession(ISessionFactory sessionFactory)
{
ISession session = SessionFactoryUtils.GetSession(sessionFactory, true);
session.FlushMode=FlushMode.Never;
return session;
}
/// <summary>
/// Close the given Session.
/// Note that this just applies in single session mode!
///
The default implementation delegates to SessionFactoryUtils'
///releaseSession method.
///
Can be overridden in subclasses, e.g. for flushing the Session before
/// closing it. See class-level javadoc for a discussion of flush handling.
///Note that you should also override getSession accordingly, to set
/// the flush mode to something else than NEVER.
/// </summary>
/// <param name="session">session the Session used for filtering</param>
/// <param name="sessionFactory">essionFactory the SessionFactory that this filter uses</param>
protected virtual void CloseSession(ISession session, ISessionFactory sessionFactory)
{
SessionFactoryUtils.ReleaseSession(session, sessionFactory);
}
}
}
see
http://bbs.dotnettools.org/NewsDetail.asp?id=5244
Mark Pollack
03-29-2006, 01:59 PM
Hi,
Thanks alot for the posting of the code. There isn't yet a module - We better damn well make one as there has been much demand. Let's start with what you posted. The change I'd like to make under the covers is to store the session in using the remoting callcontext, as suggested on another forum question (http://forum.springframework.net/viewtopic.php?t=403)- and to make it work with both .net 1.1/2.0!
I'll be in touch!
Cheers,
Mark
manuj
03-29-2006, 04:42 PM
I used this sample code to test the OpenInSessionView functionality, but HibernateTemplate is still closing the session after the first query is ran. What am I missing here?
Mark Pollack
03-29-2006, 05:48 PM
Hi,
Not yet sure. I'm gonna get it up and running on in my dev environment and investigate...
Cheers,
Mark
manuj
03-29-2006, 06:02 PM
Not 100% sure but from what i found by digging further - this keeps the session open for transactional methods only.
if i have a non-transaction method - it does not use the session provided by the OpenSessionInView module but chooses to open its own session - runs the query on that session and immediately closes it.
Aleksei Kachanov
07-31-2006, 05:35 PM
Has anybody fixed it?
Bruno Baia
08-07-2006, 09:56 AM
Hi,
just a ping back to say to users who subscribed to this post that this has been partially resolved :
http://forum.springframework.net/showthread.php?t=623
-Bruno
offtopic: perhaps move all hibernate posts to the new forum?
jnapier
08-12-2006, 01:24 AM
Im wondering if any work has been done to resolve the problem with session management when using the OpenInSessionViewModule. When using this spring-nhibernate implementation, we are losing any additional benefits that nhibernate provides beyond mapping an object to a data table. Lazy loading is completely lost because a session is closed after every operation.
I was thinking that the OpenInSessionViewModule would elimiate this problem, but it does not. It appears that a new session will be created if we the session is not listed in a transaction.
Line 189 in SessionFactoryUtils of the GetSession Method starts the block that is the culprit for making sure that all sessions must be enlisted in a transaction.
if (TransactionSynchronizationManager.Synchronization Active &&
sessionHolder.DoesNotHoldNonDefaultSession)
If this does not evaluate to true and the sessionHolder that holds the session is not Synchronized with a transaction then the GetSession Method will go about creating a new session. The previously created session in the OpenInSessionViewModule never even gets used. Next, the NHibernate action is performed and the session is closed. This process continues to happen for every single NHibernate call.
This whole module seems to think of one session to one transaction and thats it. To me, that is not going along with the NHibernate way of doing things.
Im wondering if this is how it work in the java implementation too, or if there was just some mixup in the translation. Please let me know how I can be of further assistance to help get this resolved.
Mark Pollack
08-12-2006, 01:40 AM
Hi,
Another thread (http://forum.springframework.net/showthread.php?t=641)is also discussing this topic with comments along the line you mention. This isn't an obvious mis-translation of the functionality in Spring.Java as far as I can tell. I will be having a chat with Jurgen from Spring.Java on this issue and see what his thoughts are as this also came up with Java hibernate use but it certainly seems to be a larger issue within the .NET community. A means to define pure session scope is the majority of what I am hearing. Hope to resolve this soon.
Cheers,
Mark
gooshoose
09-28-2006, 04:18 AM
“/Drawing”应用程序*的服务器错误。
--------------------------------------------------------------------------------
No value for key [NHibernate.Impl.SessionFactoryImpl] bound to thread []
说明: 执行当前 Web 请求期间,出现未处理的异常。请检 **跟踪信息,以了解有关该错误以 代**导致错误的出处的详细信息。
异常详细信息: System.InvalidOperationException: No value for key [NHibernate.Impl.SessionFactoryImpl] bound to thread []
源错误:
行 127: {
行 128: // single session mode
行 129: TransactionSynchronizationManager.UnbindResource(s essionFactory);
行 130:
行 131: logger.Debug("Closing single Hibernate Session in OpenSessionInViewFilter");
源文件: f:\other projects\components\spring.net\spring.data.nhibern ate-20060909-0352\src\spring\spring.data.nhibernate\data\nhiber nate\support\opensessioninviewmodule.cs 行: 129
**跟踪:
[InvalidOperationException: No value for key [NHibernate.Impl.SessionFactoryImpl] bound to thread []]
Spring.Transaction.Support.TransactionSynchronizat ionManager.UnbindResource(Object key) in c:\projects\daily\Spring.Net\src\Spring\Spring.Dat a\Transaction\Support\TransactionSynchronizationMa nager.cs:161
Spring.Data.NHibernate.Support.OpenSessionInViewMo dule.context_EndRequest(Object sender, EventArgs e) in f:\other projects\components\spring.net\spring.data.nhibern ate-20060909-0352\src\spring\spring.data.nhibernate\data\nhiber nate\support\opensessioninviewmodule.cs:129
System.Web.SyncEventExecutionStep.System.Web.HttpA pplication+IExecutionStep.Execute()
System.Web.HttpApplication.ExecuteStep(IExecutionS tep step, Boolean& completedSynchronously)
--------------------------------------------------------------------------------
版本信息: Microsoft .NET Framework 版本:1.1.4322.2032; ASP.NET 版本:1.1.4322.2032
Mark Pollack
11-21-2006, 06:53 AM
Hi,
Sorry for the long turnaround time, but I've fixed the bug in OpenSessionInViewModule. Thanks for leading me in the right direction. There was a mix-up in the translation of AbstractPlatformTransactionManager. Give it a shot with the latest download (http://www.springframework.net/downloads/Spring.Data.NHibernate/).
Thanks for your patience!
Mark
FYI, the key name (still in general app config settings - a section handler will be forthcoming) is shown below in case you don't use the name 'sessionFactory' for the name of your SessionFactory object..
<appSettings>
<add key="Spring.Data.NHibernate.Support.OpenSessionInViewMo dule.SessionFactoryObjectName" value="SessionFactory"/>
</appSettings>
tonglanli
01-07-2008, 07:17 AM
when i used SessionController.i got a problem like this.can any one help me:)
No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.InvalidOperationException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
Source Error:
Line 23: get
Line 24: {
Line 25: return SessionFactoryUtils.GetSession(sessionFactory, false);
Line 26: //return null;
Line 27: }
Mark Pollack
01-07-2008, 02:25 PM
Hi,
Can you clarify which version of spring.net you are using and which exact class you are referring to?
Cheers,
mark
vBulletin® v3.7.3, Copyright ©2000-2008, Jelsoft Enterprises Ltd.