2

I am using .NET 4 and NHibernate v3.3.4

So I haven't been able to reproduce this error. It is produced every few days seemingly at random.

The stacktrace is as follows.

System.NullReferenceException: Object reference not set to an instance of an object.
   at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
   at System.Collections.Generic.Dictionary`2.set_Item(TKey key, TValue value)
   at NHibernate.Impl.SessionFactoryObjectFactory.AddInstance(String uid, String name, ISessionFactory instance, IDictionary`2 properties)
   at NHibernate.Impl.SessionFactoryImpl..ctor(Configuration cfg, IMapping mapping, Settings settings, EventListeners listeners)
   at NHibernate.Cfg.Configuration.BuildSessionFactory()
   at OmsDalNhib.OmsDalConfig.GetSessionFactory()
   at OrmsReport.Extensions.Extensions.ZoneList() in d:\temp\src\OrmsReport\Extensions\Extensions.cs:line 129
   at OrmsReport.Controllers.ReportController.OutageSummaryMobile(String outagesummaryfilters, String zones, String customers) in d:\temp\src\OrmsReport\Controllers\ReportController.cs:line 149
   at lambda_method(Closure , ControllerBase , Object[] )
   at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
   at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
   at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass42.<BeginInvokeSynchronousActionMethod>b__41()
   at System.Web.Mvc.Async.AsyncResultWrapper.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.End()
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass37.<>c__DisplayClass39.<BeginInvokeActionMethodWithFilters>b__33()
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass4f.<InvokeActionMethodFilterAsynchronously>b__49()
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass37.<BeginInvokeActionMethodWithFilters>b__36(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncResultWrapper.WrappedAsyncResult`1.End()
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult)
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass25.<>c__DisplayClass2a.<BeginInvokeAction>b__20()
   at System.Web.Mvc.Async.AsyncControllerActionInvoker.<>c__DisplayClass25.<BeginInvokeAction>b__22(IAsyncResult asyncResult)

The line that seems to be throwing the error is

var session = new OmsDalConfig(BuildConfiguration.GetConnectionString())
                 .GetSessionFactory().OpenSession()

This issue seemed related, and I replicated their solution by locking the line above. Which unfortunately did not solve anything.

Thanks in advance if anyone has suggestions. And let me know if I ccan provide any other neccesary information

Edit:

BuildConfiguration.GetConnectionString()

returns a string of the form

"Data Source=(DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = myserver.com)(PORT = 6667)))(CONNECT_DATA =(SERVICE_NAME = my-service)));User ID=myuser;Password=mypassword;";

Edit 2:

As requested:

Constructor for OMSDalConfig is just assigning the connection string, and the SessionFactory is not being built every time, at least it doesnt appear so.

public class OmsDalConfig
{
    private readonly string _connectionString;
    public static ISessionFactory CurrentSessionFactory;


    public OmsDalConfig(string connectionString)
    {
        _connectionString = connectionString;
    }

    public ISessionFactory GetSessionFactory()
    {
        // Models
        var modelMapper = new ModelMapper();
        var mappingTypes = typeof(IncidentMap).Assembly.GetExportedTypes().Where(x => x.Name.EndsWith("Map")).ToArray();
        modelMapper.AddMappings(mappingTypes);

        // NHibernate config
        var nhibernateConfig = new Configuration()
                                    .DataBaseIntegration(db =>
                                    {
                                        db.Dialect<Oracle10gDialect>();
                                        db.ConnectionString = _connectionString;
                                        db.Driver<OracleClientDriver>();
                                    });

        nhibernateConfig.AddMapping(modelMapper.CompileMappingForAllExplicitlyAddedEntities());

        if (CurrentSessionFactory != null)
        {
            return CurrentSessionFactory;
        }

        CurrentSessionFactory = nhibernateConfig.BuildSessionFactory();
        return CurrentSessionFactory;
    }
}

I will try separating the session var assignment as discussed and report back. Apologies for the late reply. Thank you all again for the help.

Edit3:

I have separated the OpenSession and Build Session calls when creating the session variable (line that is throwing the exception). Ill leave it running for a while and report back if there error is thrown again or not.

Edit 4 : As stated in Edit 3. I tried splitting the calls. There error was thrown again today so thats a no go. Any other suggestions are greatly appreciated.

Community
  • 1
  • 1
jipson
  • 79
  • 1
  • 3
  • 14
  • What does `BuildConfiguration.GetConnectionString()` return? – nvoigt May 28 '15 at 14:37
  • @nvoigt see the first edit – jipson May 28 '15 at 14:58
  • What I meant is, are you *sure* that it returns that string 100% reliable? Why not put it into a variable and check it. Maybe the configuration cannot be read once in a while? – nvoigt May 28 '15 at 15:02
  • @nvoigt The method is local. Or at least local in a class library (dll) file. Im not a c# expert but I cant see it being deadlocked or unavailable for any reason. – jipson May 28 '15 at 15:21
  • It could still return an unexpected value. Or is it a compile-time static, hardcoded string? – nvoigt May 28 '15 at 16:02
  • @nvoigt Yes, the string is hardcoded. – jipson May 28 '15 at 17:07
  • Are you missing Oracle dlls in ouput? – Onur Gumus May 29 '15 at 08:08
  • i would suggest to break that single line into 3-4 line.. get conn string, get session factory, and then open session.. also you dont need to build session factory each time to open a session – harishr May 30 '15 at 10:51
  • Can you post the code for the constructor of OmsDalConfig and foe method GetSessionFactory, looks like you are creating the session factory each and every time when you wants a session – Low Flying Pelican Jun 01 '15 at 13:00
  • Sorry for late reply. I will try breaking the chain up and post the constructor code tonight, thank you for the replies. – jipson Jun 09 '15 at 13:00
  • @entre Unfortunately that didn't solve the issue – jipson Jun 19 '15 at 13:56
  • @LowFlyingPelican Thanks for the reply. Ive posted the code. I the session is not being rebuilt everytime. – jipson Jun 19 '15 at 13:57
  • Well... try moving if (CurrentSessionFactory != null) { return CurrentSessionFactory; } section to the top of the method – Low Flying Pelican Jun 20 '15 at 04:10
  • What is at reportcontroller line 149 :) – Hace Jul 30 '15 at 20:25

1 Answers1

0

Try another approach, let some IoC Container manage the life cicle of your ISessionFactory. Ex: Autofac, Castle Windsor...

This way, you will be able to decouple your dependencies, using the principle of dependency injection.

https://github.com/castleproject/Windsor/blob/master/docs/mvc-tutorial-part-6-persistence-layer.md

Without Container, you can try this approach, put the static field in the global, see that example:

https://github.com/ricardoborges/NHibernate-Samples/tree/master/src/Web/W01/NH.Sample.W01.Handler

Ricardo
  • 1,549
  • 2
  • 12
  • 11