2011-02-09 38 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

不要懶洋洋地初始化會話工廠。

在應用程序啓動時執行此操作,您將遇到的問題要少得多。