I have a tiny problem with NHibernate and I can’t figure out why. Every time I debug or profile the application and I accidently violate a unique constraint NHibernate just won’t run any more multiqueries (I’ll leave the exception stack trace till last). The flow is this. Everything works fine and then:
Violation of UNIQUE KEY constraint
‘UQ__workday__572F4CF4753864A1’.
Cannot insert duplicate key in object
‘dbo.workday’. The statement has been
terminated.Description: An unhandled exception
occurred during the execution of the
current web request. Please review the
stack trace for more information about
the error and where it originated in
the code.Exception Details:
System.Data.SqlClient.SqlException:
Violation of UNIQUE KEY constraint
‘UQ__workday__572F4CF4753864A1’.
Cannot insert duplicate key in object
‘dbo.workday’. The statement has been
terminated.terminated.
If I now try to run the same code that executes the query:
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;
That code generates the following statement
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 */
I get the following really frustrating exception. Actually from now on every query is a timeout and the application needs to be restarted before I can execute anything. Sometimes it doesn’t even help to restart it.
Does anyone know what is up with that?
at
System.Data.SqlClient.SqlConnection.OnError(SqlException
exception, Boolean breakConnection)
at
System.Data.SqlClient.SqlInternalConnection.OnError(SqlException
exception, Boolean breakConnection)
at
System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
at
System.Data.SqlClient.TdsParser.Run(RunBehavior
runBehavior, SqlCommand cmdHandler,
SqlDataReader dataStream,
BulkCopySimpleResultSet
bulkCopyHandler, TdsParserStateObject
stateObj) at
System.Data.SqlClient.SqlDataReader.ConsumeMetaData()
at
System.Data.SqlClient.SqlDataReader.get_MetaData()
at
System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader
ds, RunBehavior runBehavior, String
resetOptionsString) at
System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior
cmdBehavior, RunBehavior runBehavior,
Boolean returnStream, Boolean async)
at
System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior
cmdBehavior, RunBehavior runBehavior,
Boolean returnStream, String method,
DbAsyncResult result) at
System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior
cmdBehavior, RunBehavior runBehavior,
Boolean returnStream, String method)
at
System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior
behavior, String method) at
System.Data.SqlClient.SqlCommand.ExecuteDbDataReader(CommandBehavior
behavior) at
System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader()
at
NHibernate.AdoNet.AbstractBatcher.ExecuteReader(IDbCommand
cmd) in
d:\CSharp\NH\nhibernate\src\NHibernate\AdoNet\AbstractBatcher.cs:line
247 at
NHibernate.Impl.MultiCriteriaImpl.GetResultsFromDatabase(IList
results) in
d:\CSharp\NH\nhibernate\src\NHibernate\Impl\MultiCriteriaImpl.cs:line
209 at
NHibernate.Impl.MultiCriteriaImpl.DoList()
in
d:\CSharp\NH\nhibernate\src\NHibernate\Impl\MultiCriteriaImpl.cs:line
171 at
NHibernate.Impl.MultiCriteriaImpl.ListIgnoreQueryCache()
in
d:\CSharp\NH\nhibernate\src\NHibernate\Impl\MultiCriteriaImpl.cs:line
143 at
NHibernate.Impl.MultiCriteriaImpl.List()
in
d:\CSharp\NH\nhibernate\src\NHibernate\Impl\MultiCriteriaImpl.cs:line
91 at
FakturaLight.Repositories.InvoiceRepository.GetSingle(Int32
invoiceId) in
D:\Projekt\faktura_light\src\FakturaLight\Repositories\InvoiceRepository.cs:line
168 at
FakturaLight.WebClient.Controllers.InvoiceController.PrepareEditInvoiceModel(EditInvoiceModel
oldModel, Int32 id) in
D:\Projekt\faktura_light\src\FakturaLight.WebClient\Controllers\InvoiceController.cs:line
116 at
FakturaLight.WebClient.Controllers.InvoiceController.Edit(Int32
id) in
D:\Projekt\faktura_light\src\FakturaLight.WebClient\Controllers\InvoiceController.cs:line
82 at lambda_method(Closure ,
ControllerBase , Object[] ) at
System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase
controller, Object[] parameters) at
System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext
controllerContext, IDictionary22
parameters) at
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext
controllerContext, ActionDescriptor
actionDescriptor, IDictionary
parameters) at
System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClassd.b__a()
at
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter
filter, ActionExecutingContext
preContext, Func1 continuation)preContext, Func1 continuation)1.terminated.
It’s by design. Just create another session.
(please remember that your sessions should be opened late and closed early)