NHibernate останавливается, если ранее было нарушено уникальное ограничение - PullRequest
2 голосов
/ 06 сентября 2010

У меня небольшая проблема с NHibernate, и я не могу понять, почему. Каждый раз, когда я отлаживаю или профилирую приложение и случайно нарушаю уникальное ограничение, NHibernate больше не будет запускать несколько запросов (я оставлю трассировку стека исключений до последнего). Поток такой. Все отлично работает, а затем:

Нарушение ограничения UNIQUE KEY 'UQ__workday__572F4CF4753864A1. Невозможно вставить дубликат ключа в объект 'Dbo.workday. Заявление было прекращено.

Описание: необработанное исключение произошло во время исполнения текущий веб-запрос. Пожалуйста, просмотрите трассировка стека для получения дополнительной информации о ошибка и откуда она возникла код.

Сведения об исключении: System.Data.SqlClient.SqlException: Нарушение ограничения UNIQUE KEY 'UQ__workday__572F4CF4753864A1. Невозможно вставить дубликат ключа в объект 'Dbo.workday. Заявление было terminated.terminated.

Если я сейчас попытаюсь запустить тот же код, который выполняет запрос:

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 исключение, Boolean breakConnection)
в System.Data.SqlClient.SqlInternalConnection.OnError (SqlException исключение, Boolean breakConnection)
в System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning () в System.Data.SqlClient.TdsParser.Run (RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) в System.Data.SqlClient.SqlDataReader.ConsumeMetaData () в System.Data.SqlClient.SqlDataReader.get_MetaData () в System.Data.SqlClient.SqlCommand.FinishExecuteReader (SqlDataReader ds, RunBehavior, runBehavior, String resetOptionsString) в System.Data.SqlClient.SqlCommand.RunExecuteReaderTds (CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async)
в System.Data.SqlClient.SqlCommand.RunExecuteReader (CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, метод String, Результат DbAsyncResult) в System.Data.SqlClient.SqlCommand.RunExecuteReader (CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, метод String)
в System.Data.SqlClient.SqlCommand.ExecuteReader (CommandBehavior поведение, метод String) в System.Data.SqlClient.SqlCommand.ExecuteDbDataReader (CommandBehavior поведение) в System.Data.Common.DbCommand.System.Data.IDbCommand.ExecuteReader () в NHibernate.AdoNet.AbstractBatcher.ExecuteReader (IDbCommand cmd) в D: \ CSharp \ NH \ NHibernate \ SRC \ NHibernate \ AdoNet \ AbstractBatcher.cs: линия 247 в 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: линия 171 в NHibernate.Impl.MultiCriteriaImpl.ListIgnoreQueryCache () в D: \ CSharp \ NH \ NHibernate \ SRC \ NHibernate \ Impl \ MultiCriteriaImpl.cs: линия 143 в NHibernate.Impl.MultiCriteriaImpl.List () в D: \ CSharp \ NH \ NHibernate \ SRC \ NHibernate \ Impl \ MultiCriteriaImpl.cs: линия 91 в FakturaLight.Repositories.InvoiceRepository.GetSingle (Int32 invoiceId) в D: \ Projekt \ faktura_light \ SRC \ FakturaLight \ Хранилище \ InvoiceRepository.cs: линия 168 в FakturaLight.WebClient.Controllers.InvoiceController.PrepareEditInvoiceModel (EditInvoiceModel oldModel, Int32 id) вD: \ Projekt \ faktura_light \ src \ FakturaLight.WebClient \ Controllers \ InvoiceController.cs: строка 116 в FakturaLight.WebClient.Controllers.InvoiceController.Edit (идентификатор Int32) в D: \ Projekt \ fakturaWlight.Fakliw.light\ InvoiceController.cs: строка 82 в lambda_method (Closure, ControllerBase, Object []) в System.Web.Mvc.ActionMethodDispatcher.Execute (параметры ControllerBase, Object []) в System.Web.Mvc.ReflectedActionDescriptor.Execute (ControllerConContext), Параметры IDictionary 2 parameters) at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary 2) в System.Web.Mvc.ControllerActionInvoker. <> C__DisplayClassd.b__a () в System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter (фильтр IActionFilter, ActionExecutingContext continue 1tecontext).прекращено.

1 Ответ

5 голосов
/ 06 сентября 2010

Это по замыслу.Просто создайте другой сеанс.

Если сеанс вызывает исключение, транзакция должна быть откатана, а сеанс отброшен.

(помните, что ваши сеансыследует открывать поздно и закрывать рано)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...