Подтвердить что ты не робот

NHibernate: ошибка дегидратирующего свойства. Что это за черт?

Я делаю довольно сложную транзакцию NHibernate в финансовой системе, создавая платеж, записывая записи в книгу, проверяя, является ли платеж общей суммой счета-фактуры, если это так, что счет-фактура полностью оплачен, и т.д.... много веселья. Естественно, это должно произойти внутри одной транзакции.

Когда я пытаюсь зафиксировать изменение сеанса, я получаю следующую ошибку:

Error dehydrating property value for C3.DataModel.CFAPTransaction.Vendor

В Googling этого не оказалось много записей. Может ли кто-нибудь сказать мне, что это значит, и где мне нужно сосредоточить свои усилия по отладке?

UPDATE

По запросу, вот полное сообщение об ошибке:

NHibernate.PropertyValueException: Error dehydrating property v  alue for C3.DataModel.CFAPTransaction.Vendor --->

NHibernate.HibernateException: Невозможно разрешить свойство: APVendorId в NHibernate.Tuple.Entity.EntityMetamodel.GetPropertyIndex(строка propertyName) в NHibernate.Tuple.Entity.AbstractEntityTuplizer.GetPropertyValue(Объект объект, String propertyPath) в NHibernate.Persister.Entity.AbstractEntityPersister.GetPropertyValue(Объект obj, String propertyName, EntityMode entityMode) при NHibernate.Type.EntityType.GetIdentifier(значение объекта, ISessionImplementor) в NHibernate.Type.ManyToOneType.NullSafeSet(IDbCommand st, значение объекта, Индекс Int32, Boolean [] устанавливаемый, сеанс ISessionImplementor) в NHibernate.Persister.Entity.AbstractEntityPersister.Dehydrate(Объект id, Object [], Object rowId, Boolean [] includeProperty, Boolean [] [] includeColumns, таблица Int32, команда IDbCommand, ISessionImplementor, индекс Int32) --- Конец внутреннего исключения трассировка стека --- при NHibernate.Persister.Entity.AbstractEntityPersister.Dehydrate(Объект id, Object [], Object rowId, Boolean [] includeProperty, Boolean [] [] includeColumns, таблица Int32, команда IDbCommand, Сеанс ISessionImplementor, индекс Int32) в NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Идентификатор объекта, Object [], Boolean [] notNull, Int32 j, SqlCommandInfo sql, Object obj, сеанс ISessionImplementor) в NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Идентификатор объекта, Object [], Object obj, сеанс ISessionImplementor) в NHibernate.Action.EntityInsertAction.Execute() at NHibernate.Engine.ActionQueue.Execute(исполняемый файл IExecutable) в NHibernate.Engine.ActionQueue.ExecuteActions(список IList) в NHibernate.Engine.ActionQueue.ExecuteActions() в NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource сессии) в NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent событие) в NHibernate.Impl.SessionImpl.Flush() в NHibernate.Transaction.AdoTransaction.Commit() at C3.DataModel.Repositories.NHUnitOfWork.Save() в C:\Проекты\C3\C3.DataModel.Generated\Сформированные\NHibernateRepositories.generated.cs: линия 2659 в C3.WebUI.Areas.Finance.Controllers.AccountsPayableController.CreatePayment(CreatePaymentModel модель) в C:\проекты\С3\C3.WebUI\Области\Финансы\Контроллеры\AccountsPayableController.cs: линия 434

UPDATE Бросив NHibernate в режим DEBUG, я получаю кучу таких вещей:

каскад обработки NHibernate.Engine.CascadingAction + SaveUpdateCascadingAction для: C3.DataModel.APVendor     каскадный NHibernate.Engine.CascadingAction + SaveUpdateCascadingAction для коллекция: C3.DataModel.APVendor.Transactions     сделанный каскадом NHibernate.Engine.CascadingAction + SaveUpdateCascadingAction для коллекция: C3.DataModel.APVendor.Transactions     сделано обработка каскада NHibernate.Engine.CascadingAction + SaveUpdateCascadingAction для: C3.DataModel.APVendor     NHibernate.Event.Default.AbstractFlushingEventListener ОШИБКА Не удалось синхронизировать состояние базы данных с сеансом     NHibernate.PropertyValueException: ошибка дегидратирования значения свойства для C3.DataModel.CFAPTransaction.Vendor --- > NHibernate.HibernateException: Невозможно разрешить свойство: APVendorId в NHibernate.Tuple.Entity.EntityMetamodel.GetPropertyIndex(строка propertyName) в NHibernate.Tuple.Entity.AbstractEntityTuplizer.GetPropertyValue(Объект объект, String propertyPath) в NHibernate.Persister.Entity.AbstractEntityPersister.GetPropertyValue(Объект obj, String propertyName, EntityMode entityMode) при NHibernate.Type.EntityType.GetIdentifier(значение объекта, ISessionImplementor) в NHibernate.Type.ManyToOneType.NullSafeSet(IDbCommand st, значение объекта, Индекс Int32, Boolean [] устанавливаемый, сеанс ISessionImplementor) в NHibernate.Persister.Entity.AbstractEntityPersister.Dehydrate(Объект id, Object [], Object rowId, Boolean [] includeProperty, Boolean [] [] includeColumns, таблица Int32, команда IDbCommand, ISessionImplementor, индекс Int32) --- Конец внутреннего исключения трассировка стека --- при NHibernate.Persister.Entity.AbstractEntityPersister.Dehydrate(Объект id, Object [], Object rowId, Boolean [] includeProperty, Boolean [] [] includeColumns, таблица Int32, команда IDbCommand, Сеанс ISessionImplementor, индекс Int32) в NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Идентификатор объекта, Object [], Boolean [] notNull, Int32 j, SqlCommandInfo sql, Object obj, сеанс ISessionImplementor) в NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Идентификатор объекта, Object [], Object obj, сеанс ISessionImplementor) в NHibernate.Action.EntityInsertAction.Execute() at NHibernate.Engine.ActionQueue.Execute(исполняемый файл IExecutable) в NHibernate.Engine.ActionQueue.ExecuteActions(список IList) в NHibernate.Engine.ActionQueue.ExecuteActions() в NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource сессия)     C3.WebUI.Areas.Finance.Controllers.AccountsPayableController ERROR C3.WebUI.Areas.Finance.Controllers.AccountsPayableController: Нет дополнительной информации.     NHibernate.PropertyValueException: ошибка дегидратирования значения свойства для C3.DataModel.CFAPTransaction.Vendor --- > NHibernate.HibernateException: Невозможно разрешить свойство: APVendorId в NHibernate.Tuple.Entity.EntityMetamodel.GetPropertyIndex(строка propertyName) в NHibernate.Tuple.Entity.AbstractEntityTuplizer.GetPropertyValue(Объект объект, String propertyPath) в NHibernate.Persister.Entity.AbstractEntityPersister.GetPropertyValue(Объект obj, String propertyName, EntityMode entityMode) при NHibernate.Type.EntityType.GetIdentifier(значение объекта, ISessionImplementor) в NHibernate.Type.ManyToOneType.NullSafeSet(IDbCommand st, значение объекта, Индекс Int32, Boolean [] устанавливаемый, сеанс ISessionImplementor) в NHibernate.Persister.Entity.AbstractEntityPersister.Dehydrate(Объект id, Object [], Object rowId, Boolean [] includeProperty, Boolean [] [] includeColumns, таблица Int32, команда IDbCommand, ISessionImplementor, индекс Int32) --- Конец внутреннего исключения трассировка стека --- при NHibernate.Persister.Entity.AbstractEntityPersister.Dehydrate(Объект id, Object [], Object rowId, Boolean [] includeProperty, Boolean [] [] includeColumns, таблица Int32, команда IDbCommand, Сеанс ISessionImplementor, индекс Int32) в NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Идентификатор объекта, Object [], Boolean [] notNull, Int32 j, SqlCommandInfo sql, Object obj, сеанс ISessionImplementor) в NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Идентификатор объекта, Object [], Object obj, сеанс ISessionImplementor) в NHibernate.Action.EntityInsertAction.Execute() at NHibernate.Engine.ActionQueue.Execute(исполняемый файл IExecutable) в NHibernate.Engine.ActionQueue.ExecuteActions(список IList) в NHibernate.Engine.ActionQueue.ExecuteActions() в NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource сессии) в NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent событие) в NHibernate.Impl.SessionImpl.Flush() в NHibernate.Transaction.AdoTransaction.Commit() at C3.DataModel.Repositories.NHUnitOfWork.Save() в C:\Проекты\C3\C3.DataModel.Generated\Сформированные\NHibernateRepositories.generated.cs: линия 2659 в C3.WebUI.Areas.Finance.Controllers.AccountsPayableController.CreatePayment(CreatePaymentModel модель) в C:\проекты\С3\C3.WebUI\Области\Финансы\Контроллеры\AccountsPayableController.cs: линия 434

Не похоже, что это происходит при запросе базы данных. У меня есть чувство, что у меня есть проблемы со мной, создавая кучу объектов, связывая их, а затем пытаясь их удержать, но это чистое предположение.

4b9b3361

Ответ 1

Вероятно, что nhibernate не показывает правильное свойство ошибки, проверяет смежные свойства в файле сопоставления, ищет ошибки в отношении между типами данных из вашей базы данных и типами данных из .net или повторяющихся столбцов в свойствах... также проверьте эту ссылку Fluent NHibernate - IndexOutOfRange

Ответ 2

Вы должны проверить сопоставление CFAPTransaction. Похоже, вы хотели указать одного поставщика для каждой транзакции. В этом случае ваше сопоставление должно быть как ниже кода.

public CFAPTransactionMap()
{
  HasOne(x => x.Vendor).ForeignKey("VendorId").Cascade.All();
  ...
}

Ответ 3

В моем случае это была недостающая спецификация идентификатора на SQL-сервере.

Простой объект:

public class Employee
{
    public virtual int ID { get; set; }
}

Mapping:

public class EmployeeMap : ClassMapping<Employee>
{
    public EmployeeMap()
    {
        Id(x => x.ID, map => { map.Generator(Generators.Identity); map.UnsavedValue(0); });
    }
}

SQL:

Вот столбец идентификатора с ограничением первичного ключа.

столбец идентификаторов с ограничением

И здесь вы можете увидеть недостающую спецификацию идентификатора, которая вызывает проблему. Отсутствует спецификация идентификатора

Чтобы решить проблему, вы должны указать столбец ID как IDENTITY то есть.

CREATE TABLE EMPLOYEE
(
    ID int NOT NULL IDENTITY(0, 1)
);

Ответ 4

Я столкнулся с той же ошибкой. Это мои сопоставления с образцами:

ManyToOne(x => x.objPerson, map => { map.Column("PersonID"); map.NotNullable(false); });
Property(x => x.intPersonID, map => map.Column("PersonID"));

Если я попытался сохранить/сохранить это в своей базе данных, заполнив только свойство intPersonID и сделав нулевое значение objPerson, это приведет к ошибке дегидратации во всех ваших свойствах!

Причина, по которой я просто заполняю intPersonID, заключается в том, чтобы предотвратить запрос в базе данных, чтобы получить objPerson перед сохранением в базе данных. К сожалению, это вызовет ошибку, поэтому я изменил свои сопоставления и исправил это:

ManyToOne(x => x.objPerson, map => { map.Column("PersonID"); map.NotNullable(false); });

Или, если я хочу предотвратить запрос в базе данных, получив весь объект, я просто использую это сопоставление:

Property(x => x.intPersonID, map => map.Column("PersonID"));

Но объединение их невозможно.