BuildSessionFactory上的NHibernate NullReferenceException

时间:2015-05-28 14:35:49

标签: c# nhibernate asynchronous

我正在使用.NET 4和NHibernate v3.3.4

所以我无法重现此错误。它几乎每隔几天就会产生一次。

堆栈跟踪如下。

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)

似乎抛出错误的行是

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

This issue似乎有关系,我通过锁定上面的行来复制他们的解决方案。遗憾的是,没有解决任何问题。

如果有人有任何建议,请提前致谢。如果我可以提供任何其他必要的信息,请告诉我

编辑:

BuildConfiguration.GetConnectionString()

返回

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

编辑2:

根据要求:

OMSDalConfig的构造函数只是分配连接字符串,并且每次都没有构建SessionFactory,至少它不会出现。

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;
    }
}

我将尝试按照讨论的方式分离会话var分配并报告回来。对迟到的回复表示歉意。再次感谢大家的帮助。

EDIT3:

我在创建会话变量时抛出了OpenSession和Build Session调用(抛出异常的行)。我会让它运行一段时间并报告是否再次抛出错误。

编辑4:如编辑3中所述。我尝试拆分调用。今天再次抛出错误,所以不行。非常感谢任何其他建议。

1 个答案:

答案 0 :(得分:0)

尝试另一种方法,让一些IoC Container管理您的ISessionFactory的生命周期。例如:Autofac,Castle Windsor ......

这样,您就可以使用依赖注入原理来解耦依赖关系了。

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

如果没有Container,您可以尝试这种方法,将静态字段放在全局中,请参见示例:

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