2011-02-09 44 views
1

有时,当我的程序开始连接到Windows XP上的MS SQL 2005 EXPRESS DB时,有时会出现此异常。有时候我得到了这个错误,有时候不是。NHibernate v3数据库连接期间的Nhibernate空引用异常

DBMonitor类在单独的线程上运行,但只在一个上运行,我将来可以运行多个。

我也有类似的SessionProviderMsSql2005类,但只限于SQLite连接,它有同样的问题,对多线程运行的SQLite会话提供...

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 MySolution.DatabaseLayer.Repositories.SessionProviderMsSql2005.get_SessionFactory() 
    at MySolution.DatabaseLayer.Repositories.SessionProviderMsSql2005.OpenSession() 

还有就是我SessionProviderMsSql2005类

using System; 
using System.Collections.Generic; 
using NHibernate; 
using NHibernate.Cfg; 
using Environment = NHibernate.Cfg.Environment; 

namespace MySolution.DatabaseLayer.Repositories 
{ 
    public class SessionProviderMsSql2005 
    { 
     private static readonly object _padlock = new object(); 

     private static Configuration _configuration; 
     public static Configuration Configuration 
     { 
      get 
      { 
       lock (_padlock)//must be thread save! 
       { 
        if (_configuration == null) 
        { 

         if (string.IsNullOrEmpty(InitialCatalog)) 
         { 
          throw new NullReferenceException("Property InitialCatalog could not be null or empty!"); 
         } 

         if (string.IsNullOrEmpty(ServerName)) 
         { 
          throw new NullReferenceException("Property ServerName could not be null or empty!"); 
         } 

         _configuration = new Configuration(); 
         _configuration.Configure("Config/Hibernate.MsSql2005.cfg.xml"); 
         _configuration.AddAssembly("MySolution.DatabaseLayer"); 
         Configuration.AddProperties(new Dictionary<string, string> 
                { 
                 { Environment.ConnectionString, @"Server="+ServerName+";initial catalog="+InitialCatalog+";Integrated Security=SSPI;" } 
                }); 
        } 
        return _configuration; 
       } 
      } 
     } 

     private static ISessionFactory _sessionFactory; 
     public static ISessionFactory SessionFactory 
     { 
      get 
     { 
      lock (_padlock) 
      { 
       if (_sessionFactory == null) 
       { 
        lock (_padlock) 
        { 
         _sessionFactory = Configuration.BuildSessionFactory(); 
        } 
       } 
       return _sessionFactory; 
      } 
     } 
     } 

     public static string ServerName { get; set; } 
     public static string InitialCatalog { get; set; } 


     private SessionProviderMsSql2005() 
     { } 

     public static ISession OpenSession() 
     { 
      lock (_padlock) 
      { 
       return SessionFactory.OpenSession(); 
      } 
     } 

     public static void CloseSession() 
     { 
      lock (_padlock) 
      { 
       SessionFactory.Close(); 
      } 
     } 
    } 
} 

我正在使用这样的课程:

public class DBMonitor 
{ 
    private ISession _session; 


    public DBMonitor(string serverName, string initialCatalog) 
    { 
     SessionProviderMsSql2005.ServerName = serverName; 
     SessionProviderMsSql2005.InitialCatalog = initialCatalog; 
    } 

    public void Start() 
    { 

    _session = SessionProviderMsSql2005.OpenSession(); 

    IList data = _session.CreateSQLQuery("SELECT * FROM someTable WHERE id = 1").List(); 

     ... 
    } 
    } 

A呃想知道这是什么原因?

更新:更正SessionFactory getter。这是对的吗?

+0

您是否在多个线程中使用此代码? – 2011-02-09 09:26:54

+0

是的,DBMonitor类在单独的线程上运行,但只有一个,我将来可以运行多个。 – Simon 2011-02-09 09:43:22

+0

查看更新请。 – Simon 2011-02-09 09:45:04

回答

3

不要懒洋洋地初始化会话工厂。

在应用程序启动时执行此操作,您将遇到的问题要少得多。