2011-10-04 7 views
0

我想在我的控制檯應用程序中實現一些適當的NHibernate會話管理,但遇到一些非常奇怪的問題。有一刻,一切似乎都能正常工作,但隨機地,突然間它開始拋出一個「指定的轉換無效」異常,當試圖獲取一個特定的對象時,它似乎指向一個日期時間值,但沒有更多的信息是提供。stumped:自定義NHibernate會話管理給出「指定的強制轉換無效」異常(C#)

現在,我已經消除了任何與我的映射有關的錯誤,因爲我只是取消了除字符串字段和主鍵(這是一個GUID)之外的所有字段。儘管如此,這個例外仍然存在。此外,有問題的對象不包含任何子對象。

相反,我懷疑我如何調用我的Session,所以Session的緩存中存在一些導致此問題出於某種模糊原因的問題。

我使用的Util類來管理會議:

public static class FcoNHibernateUtil 
{ 
    private static readonly ISessionFactory sessionFactory = BuildSessionFactory(); 

    private static ISessionFactory BuildSessionFactory() 
    { 
     try 
     { 
      // Create the SessionFactory from hibernate.cfg.xml 
      return new Configuration() 
       .Configure() 
       .AddAssembly("FcoPersistence") 
       .AddAssembly("FcoLib") 
       .AddAssembly("FargoLib") 
       .BuildSessionFactory(); 
     } 
     catch (Exception ex) 
     { 
      throw ex; 
     } 
    } 

    public static ISessionFactory GetSessionFactory() 
    { 
     return sessionFactory; 
    } 

    public static ISession GetCurrentSession() 
    { 
     if (!CurrentSessionContext.HasBind(GetSessionFactory())) 
      CurrentSessionContext.Bind(GetSessionFactory().OpenSession()); 

     return GetSessionFactory().GetCurrentSession(); 
    } 

    public static void DisposeCurrentSession() 
    { 
     ISession currentSession = CurrentSessionContext.Unbind(GetSessionFactory()); 

     if (currentSession != null) 
     { 
      currentSession.Close(); 
      currentSession.Dispose(); 
     } 
    } 
} 

所以我DataObjectManager類的每一個操作的開始,我從取像這樣的會議從超類繼承的常用方法獲取會話:

public ISession GetSession() 
    { 
     return FcoNHibernateUtil.GetCurrentSession(); 
    } 

當控制檯應用程序(或單元測試)的一次掃描所有操作完成,我確保DisposeCurrentSession-方法被調用。

有什麼可以改進的,可以防止這些異常來?


EDIT

這是堆棧跟蹤:

at NHibernate.Type.DateTimeType.IsEqual(Object x, Object y) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Type\DateTimeType.cs:line 93 
at NHibernate.Type.NullableType.IsEqual(Object x, Object y, EntityMode entityMode) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Type\NullableType.cs:line 368 
at NHibernate.Type.AbstractType.IsSame(Object x, Object y, EntityMode entityMode) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Type\AbstractType.cs:line 218 
at NHibernate.Type.AbstractType.IsDirty(Object old, Object current, ISessionImplementor session) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Type\AbstractType.cs:line 110 
at NHibernate.Type.NullableType.IsDirty(Object old, Object current, Boolean[] checkable, ISessionImplementor session) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Type\NullableType.cs:line 338 
at NHibernate.Type.TypeHelper.FindDirty(StandardProperty[] properties, Object[] currentState, Object[] previousState, Boolean[][] includeColumns, Boolean anyUninitializedProperties, ISessionImplementor session) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Type\TypeHelper.cs:line 227 
at NHibernate.Persister.Entity.AbstractEntityPersister.FindDirty(Object[] currentState, Object[] previousState, Object entity, ISessionImplementor session) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Persister\Entity\AbstractEntityPersister.cs:line 3555 
at NHibernate.Event.Default.DefaultFlushEntityEventListener.DirtyCheck(FlushEntityEvent event) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Event\Default\DefaultFlushEntityEventListener.cs:line 456 
at NHibernate.Event.Default.DefaultFlushEntityEventListener.IsUpdateNecessary(FlushEntityEvent event, Boolean mightBeDirty) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Event\Default\DefaultFlushEntityEventListener.cs:line 187 
at NHibernate.Event.Default.DefaultFlushEntityEventListener.OnFlushEntity(FlushEntityEvent event) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Event\Default\DefaultFlushEntityEventListener.cs:line 43 
at NHibernate.Event.Default.AbstractFlushingEventListener.FlushEntities(FlushEvent event) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Event\Default\AbstractFlushingEventListener.cs:line 161 
at NHibernate.Event.Default.AbstractFlushingEventListener.FlushEverythingToExecutions(FlushEvent event) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Event\Default\AbstractFlushingEventListener.cs:line 60 
at NHibernate.Event.Default.DefaultAutoFlushEventListener.OnAutoFlush(AutoFlushEvent event) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Event\Default\DefaultAutoFlushEventListener.cs:line 30 
at NHibernate.Impl.SessionImpl.AutoFlushIfRequired(ISet`1 querySpaces) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 1145 
at NHibernate.Impl.SessionImpl.List(CriteriaImpl criteria, IList results) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Impl\SessionImpl.cs:line 1903 
at NHibernate.Impl.CriteriaImpl.List(IList results) in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Impl\CriteriaImpl.cs:line 265 
at NHibernate.Impl.CriteriaImpl.List[T]() in d:\CSharp\NH\NH\nhibernate\src\NHibernate\Impl\CriteriaImpl.cs:line 276 
at FcoPersistence.GlobalLoginSettingsManager.GetGlobalLoginSettings(String ownIdent) in C:\Users\steemfe1\Documents\Work\Code\Epimetheus\branches\Refactoring\FcoPersistence\GlobalLoginSettingsManager.cs:line 189 

,並且該方法在那裏發生:

public GlobalLoginSettings GetGlobalLoginSettings(string ownIdent) 
    { 
     session = GetSession();//if(session == null) session = Factory.OpenSession(); 
     ITransaction tx = session.BeginTransaction(); 

     GlobalLoginSettings owner; 

     try 
     { 
      ICriteria criteria = session.CreateCriteria(typeof (GlobalLoginSettings)); 

      criteria.Add(Restrictions.Eq("OWNIdent", ownIdent)); 

      var owners = criteria.List<GlobalLoginSettings>(); //<--- exception thrown 

      tx.Commit(); 

      owner = owners.Count > 0 ? owners[0] : null; 
     } 
     catch (Exception e) 
     { 
      tx.Rollback(); 
      throw e; 
     } 
     return owner; 
    } 

EDIT2:

我得到一個線索,那就是當會話在獲取對象時自動刷新時發生這種情況。所以它看起來像是從早期事務處理的會話中發生的錯誤,但還沒有被刷新。所以這個問題潛伏在會話中,直到它再次被使用。

+0

請顯示例外的全文 - 這將告訴我們它正在嘗試投射什麼。 –

回答

0

我正在訴諸不重新使用Session,而是使用SessionFactory。這有幫助。

0

最簡單的方法是將NHibernate源文件提取到某處,將Visual Studio指向它,並檢查哪個值在投射到DateTime時會拋出異常。然後在調用堆棧中進行一些步驟以找到值所在的對象。這樣您應該能夠找到錯誤。

+0

我會試一試。 –

+0

我得到一個線索,那就是當獲取對象時會話被自動刷新時發生這種情況。所以它看起來像是從早期事務處理的會話中發生的錯誤,但還沒有被刷新。所以這個問題潛伏在會話中,直到它再次被使用。 –

相關問題