2

I am currently using NHibernate with Spring.Net and using Spring's Open Session In View module. As far as I can tell, this module only opens the session on BeginRequest and closes it on EndRequest. It does not actually commit or flush the session on EndRequest.

I know that you can use Spring's [Transaction] attribute to decorate individual service methods which will perform a commit at the end of the method, but I do not want to use this technique.

Is there any way to setup Spring's OSIV module so that it will flush the session on EndRequest? If not, is there an easy way to implement my own Open Session In View which would achieve this?

I have tried to implement the "session per web request" example from the NH 3 Cookbook, but it throws an error on CurrentSessionContext:

    protected void Application_BeginRequest(object sender, EventArgs e)
    {
        var sessionFactory = (ISessionFactory) ContextRegistry.GetContext().GetObject("MySessionFactory");
        var session = sessionFactory.OpenSession(); 
        CurrentSessionContext.Bind(session);
    }

    protected void Application_EndRequest(object sender, EventArgs e)
    {
        var sessionFactory = (ISessionFactory)ContextRegistry.GetContext().GetObject("MySessionFactory");
        var session = CurrentSessionContext.Unbind(sessionFactory);
        session.Dispose();
    }

Note: The above code only tries to replicate what Spring.Net is currently doing. I was planning on updating this to flush the session after I got it working.

I'm assuming that the above code is not working because I am using Spring.Net to setup NH and its SessionFactory which may make the example in the book invalid.

Any help/advice would be greatly appreciated.

I am using NHibernate 3.2 and Spring 1.3.2

Edit:

After reading http://forum.springsource.org/archive/index.php/t-16949.html I'm beginning to wonder if a transaction per request is a good idea.

Rezler
  • 1,064
  • 1
  • 8
  • 21
  • 1
    There are some strong reasons why the flush mode is set to FlushMode.NEVER: http://forum.springframework.net/showthread.php?3303-OpenSessionInViewModule _Having FlushMode.NEVER on OSIV is by design. This is because if OSIV flushed pending changes during "EndRequest" and an error occurs, all response has already been sent to the client. There would be no way of telling the client about the error. Thus it is possible to change the default FlushMode but I wouldn't recommend it._ – Andreas Sep 04 '11 at 13:05
  • @Andreas I have now backed down from my original idea. The main reason behind my original thinking was because we have an existing web app that has a lot of business logic in code behinds. I thought it would be simpler to update OSIV to commit on EndRequest, rather than having to refactor the code into service methods with Transaction attributes on them. But it looks like I'm going to have to bite the bullet on this one. If you want to put an answer in for this advising against what I suggested, then I will gladly accept it. Thanks. – Rezler Sep 04 '11 at 19:24

2 Answers2

2

There are some strong reasons why the flush mode is set to FlushMode.NEVER: http://forum.springframework.net/showthread.php?3303-OpenSessionInViewModule

Erich Eichinger (SpringSource GmbH)

Having FlushMode.NEVER on OSIV is by design. This is because if OSIV flushed pending changes during "EndRequest" and an error occurs, all response has already been sent to the client. There would be no way of telling the client about the error. Thus it is possible to change the default FlushMode but I wouldn't recommend it.

That said, there is an undocumented feature. You can set the flush mode by setting an appSettings key/value pair in your web.config:

<configuration>
  <appSettings>
    ...
    <add 
      key="Spring.Data.NHibernate.Support.OpenSessionInViewModule.DefaultFlushMode"
      value="Auto" 
      />
  </appSettings>
  ...
</configuration>
Andreas
  • 5,251
  • 30
  • 43
-1

I'm not familiar with Spring.NET, but: session factory should be just one for whole application. Details here. Session is opened at each request's begin.

I don't know whether this changed in NH3, but in our NH 2 app we build session factory this way:

NHibernateConfiguration.BuildSessionFactory()
Community
  • 1
  • 1
jirkamat
  • 1,776
  • 2
  • 15
  • 17
  • 1
    This really doesn't address what I'm asking. Spring.Net is building the SessionFactory at Application Start. – Rezler Sep 03 '11 at 19:17