2017-10-10 313 views
1

我的控制器:重複項 'XXX' 爲NHibernate的極光鍵 '主要'(MySQL的)

using (ISession session = NHibernateSessionPerRequest.GetCurrentSession()) 
{ 
    using (ITransaction transaction = session.BeginTransaction()) 
    { 
     try 
     { 
      // Changed for the sake of simplicity. 
      // What I meant was entities being saved without using Flush() 

      var asset = new Asset() { name = "test" }; 
      session.Save(asset); 

      var story = new Story(); 
      session.Save(story); 

      asset.stories.Add(story); 
      session.Save(asset); 

      var color = new Color() { name = colorName }; 
      color.asset = asset; 
      session.Save(color); 

      transaction.Commit(); 

      return Json(new { Status = "OK" }); 
     } 
     catch (Exception ex) 
     { 
      if (!transaction.WasCommitted) 
      { 
       transaction.Rollback(); 
      } 

      return Json(new { Status = "NOK", Mensagem = ex.Message, }); 
     } 
    } 
} 

我的映射:

public AssetMap() 
{ 
    Id(x => x.id).GeneratedBy.Increment(); 
    Map(x => x.name); 
    HasMany(x => x.stories); 
} 

public StoryMap() 
{ 
    Id(x => x.id).GeneratedBy.Increment(); 
} 

public ColorMap() 
{ 
    Id(x => x.id).GeneratedBy.Increment(); 
    Map(x => x.name); 
    References(x => x.asset); 
} 

所有的ID列是自動遞增。

似乎一切都很好,但每過一段時間我得到這個錯誤:

Duplicate entry 'XXX' for key 'PRIMARY' transaction could not insert: [K1.Domain.Story#XXX][SQL: INSERT INTO Story (id) VALUES (?)]

OR

Duplicate entry 'YYY' for key 'PRIMARY' transaction could not insert: [K1.Domain.Color#YYY][SQL: INSERT INTO Color (name, asset_id, id) VALUES (?, ?, ?)]

錯誤從不與資產(第一實體保存)發生,只是故事或顏色實體。

錯誤消息是絕對正確的,因爲它確實存在於數據庫中的ID = XXX的故事(或ID爲YYY的顏色),由另一個用戶在我之前添加。

背景信息:

  • 在我看來,這是一個併發的問題。 我知道ISession不是線程安全的,但它看起來很蹩腳MySQL或NHibernate不知道如何處理它。所以,我很確定我做錯了什麼。

  • 我認爲這個錯誤是間歇性發生的,只是因爲並不總是會有另一個Story或Color與MySQL/NHibernate嘗試使用的相同ID。

  • 我們從SQL Server遷移,我們的代碼工作得很好。 我們花了最後3天的時間挖掘這一切,但都沒有成功。

  • 我沒有設置任何ID。 我不知道它是否合理......但我認爲NHibernate爲Color/Story提供了一個ID(此時可用),但是當我提交事務時,ID不再可用。

一兩件事,可以幫助...

在我的最後一次測試,NH​​ibernate的試圖挽救故事與ID = 320962(已經存在),然後.NET發射除外。

然後我再次單擊保存按鈕,NHibernate試圖保存ID = 320963(320962 + 1)的故事。

然後,我點擊第三次保存按鈕,NHibernate嘗試保存ID = 320964(320962 + 2)的故事。

之後沒有工作,因爲所有這3個ID都不可用。 NHibernate是否設想「記住」這些ID?

回答

0

我只是需要改變我的映射:

Id(x => x.id).GeneratedBy.Identity(); 

看來MySQL的處理方式不同SQL Server會自動增量列。

+0

接受你的答案! –