2011-03-31 93 views
2

我遇到了一些NHibernate Code.Basically問題,我試圖保持會話生存期儘可能短,以儘量減少應用程序中的狀態信息。NHibernate:當持久化對象出現意外會話故障

我覺得很難描述我的問題沒有具體,所以我會繼續前進,並使用文章和類別隱喻。

public class Article 
{ 
    public virtual long Id { get; set; } 
    public virtual string Name { get; set; } 
    public virtual Category Category { get; set; } 
} 
public class Category 
{ 
    public virtual long Id { get; set; } 
    public virtual string Name { get; set; } 
    public override string ToString() { return "cat-" + this.Id.ToString(); } 
} 
public class ArticleMapping : ClassMap<Article> 
{ 
    public ArticleMapping() 
    { 
     this.Id(x => x.Id, "id").GeneratedBy.Assigned(); 
     this.Map(x => x.Name, "name"); 
     this.References(x => x.Category).Fetch.Join().Cascade.None(); 
    } 
} 
public class CategoryMapping : ClassMap<Category> 
{ 
    public CategoryMapping() 
    { 
     this.ReadOnly(); 
     this.Id(x => x.Id, "id").GeneratedBy.Assigned(); 
     this.Map(x => x.Name, "name"); 
    } 
} 

我要做的就是創建一個新的,給它一個名字,從通過下面描述的方法加載列表分配類別並嘗試保存。

我得到以下警告:

無法確定是否CAT-1與分配的標識符是瞬時的或脫

如果你看看模型和映射代碼,你會看到貓1不應該被堅持 - 它是一個類別和定義只讀和非級聯。

//code that loads the list of categories 
IStatelessSession session = this.SessionService.GetStatelessSession(); 
IList<Category> cats = session.CreateCriteria<Category>().List<Category>(); 
this.SessionService.EndSession(session); 

//code that's called to save the instance 
ISession session = this.SessionService.GetSession(); 
using (ITransaction transaction = session.BeginTransaction()) 
{ 
    session.SaveOrUpdate(article); 
    transaction.Commit(); 
} 
this.SessionService.EndSession(session); 

如果我再次調用Save方法,這一切都香蕉形:

例外:

NHibernate.StaleStateException:意外的行數:0;預計:1

堆棧跟蹤:

在NHibernate.AdoNet.Expectations.BasicExpectation.VerifyOutcomeNonBatched(的Int32 rowCount時,IDbCommand的語句) 在NHibernate.AdoNet.NonBatchingBatcher.AddToBatch(IExpectation期望)

at NHibernate.Persister.Entity.AbstractEntityPersister.Update(Object id,Object [] fields, Object [] oldFields,Object rowId,Boolean [] includeProperty,Int32 j,Object oldVersion,Object obj,SqlCommandInfo sql,ISessionImplementor sessi )

at NHibernate.Persister.Entity.AbstractEntityPersister.UpdateOrInsert(Object id,Object [] fields,Object [] oldFields,Object rowId,Boolean [] includeProperty,Int32 j,Object oldVersion,Object obj,SqlCommandInfo sql, ISessionImplementor會話)

在NHibernate.Persister.Entity.AbstractEntityPersister.Update(對象ID,對象[]字段的Int32 []類型的dirtyFieldA第一次機會異常 'NHibernate.StaleStateException' 發生在NHibernate.dll S,布爾hasDirtyCollection ,Object [] oldFields,Object oldVersion,Object obj,Object rowId,ISessionImplementor session)

at NHibernate.Action.Ent ityUpdateAction.Execute()

在NHibernate.Engine.ActionQueue.Execute(IExecutable可執行)

在NHibernate.Engine.ActionQueue。ExecuteActions(IList的列表)

在NHibernate.Engine.ActionQueue.ExecuteActions()

在NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource會話)

我曾經認爲NHibernate的是無黑魔法,但這使我想拜訪我的伏都教牧師向其他領域尋求幫助......

有沒有人有任何想法,哪裏StaleStateException來自?這次我錯了哪裏?

在此先感謝

塞比

回答

1

Yuck!有時候,在向全世界大聲呼喊之前檢查所有本地的東西是有幫助的......有一個數據庫觸發器覆蓋了NHibernate從序列中提取的ID。

含義:

  • 的警告是充分理解,如 分配給 文章的類別沒有會話狀態,從而使 hasto通過確定取或可替代地 session.Refresh( ), ,它有相同的結果。

  • 的StaleObjectStateException不得不 發生,自排,是 持續性,不能設在 表(感謝,觸發先生!)

抱歉打擾你們。 ..

+0

我正在做一些不同的事情,但我也有一個觸發器在某些條件下改變了ID。所以,謝謝你回答你自己的問題。你從沮喪時間中拯救了我。 – Krauss 2017-03-22 02:58:55

2

不知道,但這個問題可能是您加載使用一個會話對象,並使用另一個更新的事實。
在這種情況下,對象確實是分離的。
嘗試使用Bind()函數將對象綁定到第二個會話,或考慮只使用一個會話(請注意,會話!= db連接。含義 - 打開會話不應該太昂貴,並且不是太差理念)。

+0

我引用的初始警告可能會回到這個事實,類別在session1中加載,而文件在session2中存儲。由於session1是無狀態的,因此應該像處理瞬態對象一樣...... Bind方法屬於哪個類? – 2011-04-01 06:31:41