2010-09-06 46 views
2

我有一个NHibernate的小问题,我找不出原因。每当我调试或者剖析应用程序时,我意外地违反了一个唯一的约束,NHibernate就不会再运行多重查询了(我将把异常堆栈跟踪留到最后)。流程就是这样。一切工作正常,然后:如果以前违反了唯一约束,NHibernate会停止

违反UNIQUE KEY约束 'UQ__workday__572F4CF4753864A1'。 无法在对象 'dbo.workday'中插入重复密钥。该声明已被终止 。

描述:在执行 当前Web请求期间发生未处理的异常 。请查看 堆栈跟踪以了解有关 错误的更多信息,以及它源自 的代码。

异常详细信息: System.Data.SqlClient.SqlException:违反 UNIQUE KEY约束 'UQ__workday__572F4CF4753864A1' 的。 无法在对象 'dbo.workday'中插入重复密钥。该声明已被终止,终止了 。

如果我现在尝试运行执行查询相同的代码:

var query1 = QueryOver.Of<Invoice>() 
    .Fetch(x => x.Company).Eager 
    .Fetch(x => x.Workdays).Eager 
    .Where(x => x.Id == invoiceId); 

var query2 = QueryOver.Of<Invoice>() 
    .Fetch(x => x.Company).Eager 
    .Fetch(x => x.Products).Eager 
    .Where(x => x.Id == invoiceId); 

var result = Session.CreateMultiCriteria() 
    .Add(query1) 
    .Add(query2) 
    .List(); 

var invoice = ((IList) result[0])[0] as Invoice; 

if (invoice != null) { 
    invoice.CalculateTotals(); 
} 

return invoice; 

该代码生成下面的语句

SELECT this_.invoice_id   as invoice1_10_2_, 
     this_.invoice_number  as invoice2_10_2_, 
     this_.invoice_prefix  as invoice3_10_2_, 
     this_.start_date   as start4_10_2_, 
     this_.end_date   as end5_10_2_, 
     this_.period    as period10_2_, 
     this_.km     as km10_2_, 
     this_.km_price   as km8_10_2_, 
     this_.hour_price   as hour9_10_2_, 
     this_.gst    as gst10_2_, 
     this_.customer_id  as customer11_10_2_, 
     this_.printed   as printed10_2_, 
     this_.created_at   as created13_10_2_, 
     this_.created_by   as created14_10_2_, 
     this_.updated_at   as updated15_10_2_, 
     this_.updated_by   as updated16_10_2_, 
     this_.deleted_at   as deleted17_10_2_, 
     this_.deleted_by   as deleted18_10_2_, 
     this_.company_id   as company19_10_2_, 
     workdays2_.invoice_id as invoice10_4_, 
     workdays2_.workday_id as workday1_4_, 
     workdays2_.workday_id as workday1_15_0_, 
     workdays2_.created_at as created2_15_0_, 
     workdays2_.created_by as created3_15_0_, 
     workdays2_.updated_at as updated4_15_0_, 
     workdays2_.updated_by as updated5_15_0_, 
     workdays2_.quantity  as quantity15_0_, 
     workdays2_.unit_price as unit7_15_0_, 
     workdays2_.day   as day15_0_, 
     workdays2_.description as descript9_15_0_, 
     workdays2_.invoice_id as invoice10_15_0_, 
     company3_.company_id  as company1_12_1_, 
     company3_.created_at  as created2_12_1_, 
     company3_.created_by  as created3_12_1_, 
     company3_.updated_at  as updated4_12_1_, 
     company3_.updated_by  as updated5_12_1_, 
     company3_.name   as name12_1_, 
     company3_.bankgiro_nr as bankgiro7_12_1_, 
     company3_.invoice_prefix as invoice8_12_1_, 
     company3_.moms_reg_nr as moms9_12_1_, 
     company3_.plus_giro_nr as plus10_12_1_, 
     company3_.contact_person as contact11_12_1_, 
     company3_.email   as email12_1_, 
     company3_.mobile   as mobile12_1_, 
     company3_.phone   as phone12_1_, 
     company3_.fax   as fax12_1_ 
FROM [invoice] this_ 
     left outer join [workday] workdays2_ 
     on this_.invoice_id = workdays2_.invoice_id 
     left outer join [company] company3_ 
     on this_.company_id = company3_.company_id 
WHERE this_.invoice_id = 351 /* @p0 */ 
SELECT this_.invoice_id   as invoice1_10_2_, 
     this_.invoice_number  as invoice2_10_2_, 
     this_.invoice_prefix  as invoice3_10_2_, 
     this_.start_date   as start4_10_2_, 
     this_.end_date   as end5_10_2_, 
     this_.period    as period10_2_, 
     this_.km     as km10_2_, 
     this_.km_price   as km8_10_2_, 
     this_.hour_price   as hour9_10_2_, 
     this_.gst    as gst10_2_, 
     this_.customer_id  as customer11_10_2_, 
     this_.printed   as printed10_2_, 
     this_.created_at   as created13_10_2_, 
     this_.created_by   as created14_10_2_, 
     this_.updated_at   as updated15_10_2_, 
     this_.updated_by   as updated16_10_2_, 
     this_.deleted_at   as deleted17_10_2_, 
     this_.deleted_by   as deleted18_10_2_, 
     this_.company_id   as company19_10_2_, 
     products2_.invoice_id as invoice10_4_, 
     products2_.product_id as product1_4_, 
     products2_.product_id as product1_13_0_, 
     products2_.created_at as created2_13_0_, 
     products2_.created_by as created3_13_0_, 
     products2_.updated_at as updated4_13_0_, 
     products2_.updated_by as updated5_13_0_, 
     products2_.quantity  as quantity13_0_, 
     products2_.profit_rate as profit7_13_0_, 
     products2_.unit_price as unit8_13_0_, 
     products2_.description as descript9_13_0_, 
     products2_.invoice_id as invoice10_13_0_, 
     company3_.company_id  as company1_12_1_, 
     company3_.created_at  as created2_12_1_, 
     company3_.created_by  as created3_12_1_, 
     company3_.updated_at  as updated4_12_1_, 
     company3_.updated_by  as updated5_12_1_, 
     company3_.name   as name12_1_, 
     company3_.bankgiro_nr as bankgiro7_12_1_, 
     company3_.invoice_prefix as invoice8_12_1_, 
     company3_.moms_reg_nr as moms9_12_1_, 
     company3_.plus_giro_nr as plus10_12_1_, 
     company3_.contact_person as contact11_12_1_, 
     company3_.email   as email12_1_, 
     company3_.mobile   as mobile12_1_, 
     company3_.phone   as phone12_1_, 
     company3_.fax   as fax12_1_ 
FROM [invoice] this_ 
     left outer join [product] products2_ 
     on this_.invoice_id = products2_.invoice_id 
     left outer join [company] company3_ 
     on this_.company_id = company3_.company_id 
WHERE this_.invoice_id = 351 /* @p1 */ 

我得到以下很无奈例外。实际上,从现在开始,每个查询都是超时,并且在我可以执行任何操作之前,应用程序需要重新启动。有时它甚至无法帮助重新启动它。

有人知道这是怎么回事吗?

在 System.Data.SqlClient.SqlConnection.OnError(SQLEXCEPTION 例外,布尔breakConnection)
在 System.Data.SqlClient.SqlInternalConnection.OnError(SQLEXCEPTION 例外,布尔breakConnection)
在 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning() 在 System.Data.SqlClient.TdsParser.Run(runBehavior runBehavior,SqlCommand的cmdHandler, SqlDataReader的数据流, 散装CopySimpleResultSet bulkCopyHandler,TdsParserStateObject stateObj)在 System.Data.SqlClient.SqlDataReader.ConsumeMetaData() 在 System.Data.SqlClient.SqlDataReader.get_MetaData() 在 System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader的 DS,runBehavior runBehavior,字符串 resetOptionsString)在 System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(的CommandBehavior cmdBehavior,runBehavior runBehavior, 布尔returnStream,布尔异步)
在 System.Data.SqlClient.SqlCommand。RunExecuteReader(的CommandBehavior cmdBehavior,RunBehavior runBehavior, 布尔returnStream,字符串方法, DbAsyncResult结果)在 System.Data.SqlClient.SqlCommand.RunExecuteReader(的CommandBehavior cmdBehavior,RunBehavior runBehavior, 布尔returnStream,字符串方法)
在 System.Data.SqlClient.SqlCommand.ExecuteReader(的CommandBehavior 行为,字符串方法)在 System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(的CommandBehavior 行为)在 System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader () at NH ibernate.AdoNet.AbstractBatcher.ExecuteReader(IDbCommand的 CMD)在 d:\ CSHARP \ NH \的nhibernate \ SRC \ NHibernate的\ ADONET \ AbstractBatcher.cs:线 NHibernate.Impl.MultiCriteriaImpl.GetResultsFromDatabase(IList的 结果)在 d:\ CSHARP \ NH \的nhibernate \ SRC \ NHibernate的\默认地将Impl \ MultiCriteriaImpl.cs:线 209在 NHibernate.Impl.MultiCriteriaImpl.DoList() 在 d:\ CSHARP \ NH \的nhibernate \ SRC \ NHibernate的\默认地将Impl \ MultiCriteriaImpl.cs:线 NHibernate.Impl.MultiCriteriaImpl.ListIgnoreQueryCache() 在 d:\ CSHARP \ NH \的nhibernate \ SRC \ NHibernate的\默认地将Impl \ MultiCriteriaImpl.cs:线 NHibernate.Impl.MultiCriteriaImpl.List() 在 d:\ CSHARP \ NH \的nhibernate \ SRC \ NHibernate的\默认地将Impl \ MultiCriteriaImpl.cs:线 FakturaLight.Repositories.InvoiceRepository.GetSingle(的Int32 invoiceId)在 d:\ Projekt的\ faktura_light \ SRC \ FakturaLight \库\ InvoiceRepository.cs:线 FakturaLight.WebClient.Controllers.InvoiceController.PrepareEditInvoiceModel(EditInvoiceModel oldModel,的Int32 ID)在 d:\ Projekt的\ faktura_light \ src \ FakturaLight.WebClient \ Controllers \ InvoiceController.cs:行 116 at FakturaLight.WebClient.Controllers.InvoiceController.E DIT(的Int32 ID)在 d:\ Projekt的\ faktura_light \ SRC \ FakturaLight.WebClient \控制器\ InvoiceController.cs:在lambda_method线 82(封闭, ControllerBase,对象[])在 System.Web.Mvc。 ActionMethodDispatcher.Execute在 System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerBase 控制器,对象[]参数)(controllerContext controllerContext,IDictionary的参数)在 System.Web.Mvc.ControllerActionInvoker。 <> c__DisplayClassd.b__a() 在 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter 滤波器,ActionExecutingContext preContext,函数功能1 continuation)preContext, Func 1续)1.terminated。

回答

5

这是设计。只需创建另一个会话。

如果Session抛出异常, 交易必须回滚 和会话丢弃。

(请记住,你的会议应晚开早闭)

+0

DOH!我已经知道了! – mhenrixon 2010-09-06 19:22:14

+0

我实际上正在考虑这件事,昨天我并没有因为我目前运行的大型交易而感到高兴。将不得不等到下一个版本。 :)谢谢 – mhenrixon 2010-09-06 20:51:52

+0

我不怪你,我有太多的代码不尊重这个原则... – 2010-09-06 21:00:29