Вопрос по nhibernate, c# – NHibernate: Ошибка обезвоживания собственности - что это за хрень?

18

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

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

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

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

UPDATE

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

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

NHibernate.HibernateException: Unable to resolve property: APVendorId at NHibernate.Tuple.Entity.EntityMetamodel.GetPropertyIndex(String propertyName) at NHibernate.Tuple.Entity.AbstractEntityTuplizer.GetPropertyValue(Object entity, String propertyPath) at NHibernate.Persister.Entity.AbstractEntityPersister.GetPropertyValue(Object obj, String propertyName, EntityMode entityMode) at NHibernate.Type.EntityType.GetIdentifier(Object value, ISessionImplementor session) at NHibernate.Type.ManyToOneType.NullSafeSet(IDbCommand st, Object value, Int32 index, Boolean[] settable, ISessionImplementor session) at NHibernate.Persister.Entity.AbstractEntityPersister.Dehydrate(Object id, Object[] fields, Object rowId, Boolean[] includeProperty, Boolean[][] includeColumns, Int32 table, IDbCommand statement, ISessionImplementor session, Int32 index) --- End of inner exception stack trace --- at NHibernate.Persister.Entity.AbstractEntityPersister.Dehydrate(Object id, Object[] fields, Object rowId, Boolean[] includeProperty, Boolean[][] includeColumns, Int32 table, IDbCommand statement, ISessionImplementor session, Int32 index) at NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Object id, Object[] fields, Boolean[] notNull, Int32 j, SqlCommandInfo sql, Object obj, ISessionImplementor session) at NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Object id, Object[] fields, Object obj, ISessionImplementor session) at NHibernate.Action.EntityInsertAction.Execute() at NHibernate.Engine.ActionQueue.Execute(IExecutable executable) at NHibernate.Engine.ActionQueue.ExecuteActions(IList list) at NHibernate.Engine.ActionQueue.ExecuteActions() at NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource session) at NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent event) at NHibernate.Impl.SessionImpl.Flush() at NHibernate.Transaction.AdoTransaction.Commit() at C3.DataModel.Repositories.NHUnitOfWork.Save() in C:\projects\C3\C3.DataModel.Generated\Generated\NHibernateRepositories.generated.cs:line 2659 at C3.WebUI.Areas.Finance.Controllers.AccountsPayableController.CreatePayment(CreatePaymentModel model) in C:\projects\C3\C3.WebUI\Areas\Finance\Controllers\AccountsPayableController.cs:line 434

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

processing cascade NHibernate.Engine.CascadingAction+SaveUpdateCascadingAction for: C3.DataModel.APVendor cascade NHibernate.Engine.CascadingAction+SaveUpdateCascadingAction for collection: C3.DataModel.APVendor.Transactions done cascade NHibernate.Engine.CascadingAction+SaveUpdateCascadingAction for collection: C3.DataModel.APVendor.Transactions done processing cascade NHibernate.Engine.CascadingAction+SaveUpdateCascadingAction for: C3.DataModel.APVendor NHibernate.Event.Default.AbstractFlushingEventListener ERROR Could not synchronize database state with session NHibernate.PropertyValueException: Error dehydrating property value for C3.DataModel.CFAPTransaction.Vendor ---> NHibernate.HibernateException: Unable to resolve property: APVendorId at NHibernate.Tuple.Entity.EntityMetamodel.GetPropertyIndex(String propertyName) at NHibernate.Tuple.Entity.AbstractEntityTuplizer.GetPropertyValue(Object entity, String propertyPath) at NHibernate.Persister.Entity.AbstractEntityPersister.GetPropertyValue(Object obj, String propertyName, EntityMode entityMode) at NHibernate.Type.EntityType.GetIdentifier(Object value, ISessionImplementor session) at NHibernate.Type.ManyToOneType.NullSafeSet(IDbCommand st, Object value, Int32 index, Boolean[] settable, ISessionImplementor session) at NHibernate.Persister.Entity.AbstractEntityPersister.Dehydrate(Object id, Object[] fields, Object rowId, Boolean[] includeProperty, Boolean[][] includeColumns, Int32 table, IDbCommand statement, ISessionImplementor session, Int32 index) --- End of inner exception stack trace --- at NHibernate.Persister.Entity.AbstractEntityPersister.Dehydrate(Object id, Object[] fields, Object rowId, Boolean[] includeProperty, Boolean[][] includeColumns, Int32 table, IDbCommand statement, ISessionImplementor session, Int32 index) at NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Object id, Object[] fields, Boolean[] notNull, Int32 j, SqlCommandInfo sql, Object obj, ISessionImplementor session) at NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Object id, Object[] fields, Object obj, ISessionImplementor session) at NHibernate.Action.EntityInsertAction.Execute() at NHibernate.Engine.ActionQueue.Execute(IExecutable executable) at NHibernate.Engine.ActionQueue.ExecuteActions(IList list) at NHibernate.Engine.ActionQueue.ExecuteActions() at NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource session) C3.WebUI.Areas.Finance.Controllers.AccountsPayableController ERROR C3.WebUI.Areas.Finance.Controllers.AccountsPayableController: No additional information. NHibernate.PropertyValueException: Error dehydrating property value for C3.DataModel.CFAPTransaction.Vendor ---> NHibernate.HibernateException: Unable to resolve property: APVendorId at NHibernate.Tuple.Entity.EntityMetamodel.GetPropertyIndex(String propertyName) at NHibernate.Tuple.Entity.AbstractEntityTuplizer.GetPropertyValue(Object entity, String propertyPath) at NHibernate.Persister.Entity.AbstractEntityPersister.GetPropertyValue(Object obj, String propertyName, EntityMode entityMode) at NHibernate.Type.EntityType.GetIdentifier(Object value, ISessionImplementor session) at NHibernate.Type.ManyToOneType.NullSafeSet(IDbCommand st, Object value, Int32 index, Boolean[] settable, ISessionImplementor session) at NHibernate.Persister.Entity.AbstractEntityPersister.Dehydrate(Object id, Object[] fields, Object rowId, Boolean[] includeProperty, Boolean[][] includeColumns, Int32 table, IDbCommand statement, ISessionImplementor session, Int32 index) --- End of inner exception stack trace --- at NHibernate.Persister.Entity.AbstractEntityPersister.Dehydrate(Object id, Object[] fields, Object rowId, Boolean[] includeProperty, Boolean[][] includeColumns, Int32 table, IDbCommand statement, ISessionImplementor session, Int32 index) at NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Object id, Object[] fields, Boolean[] notNull, Int32 j, SqlCommandInfo sql, Object obj, ISessionImplementor session) at NHibernate.Persister.Entity.AbstractEntityPersister.Insert(Object id, Object[] fields, Object obj, ISessionImplementor session) at NHibernate.Action.EntityInsertAction.Execute() at NHibernate.Engine.ActionQueue.Execute(IExecutable executable) at NHibernate.Engine.ActionQueue.ExecuteActions(IList list) at NHibernate.Engine.ActionQueue.ExecuteActions() at NHibernate.Event.Default.AbstractFlushingEventListener.PerformExecutions(IEventSource session) at NHibernate.Event.Default.DefaultFlushEventListener.OnFlush(FlushEvent event) at NHibernate.Impl.SessionImpl.Flush() at NHibernate.Transaction.AdoTransaction.Commit() at C3.DataModel.Repositories.NHUnitOfWork.Save() in C:\projects\C3\C3.DataModel.Generated\Generated\NHibernateRepositories.generated.cs:line 2659 at C3.WebUI.Areas.Finance.Controllers.AccountsPayableController.CreatePayment(CreatePaymentModel model) in C:\projects\C3\C3.WebUI\Areas\Finance\Controllers\AccountsPayableController.cs:line 434

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

Что является полным исключением, и есть ли внутреннее исключение? Preet Sangha
Если это так, я бы уменьшил размер графика в сохранении, пока он не заработает и не начнет работать в обратном направлении. Если это не помогло - я могу даже получить исходный код nhibernate. Но на данный момент, если все, что вы делаете, - это создание графа объектов, тогда, возможно, пришло время упростить граф и попробовать немного по очереди. Preet Sangha
как насчетUnable to resolve property: APVendorId - это дает вам ключ? Неверное отображение?NHUnitOfWork.Save() пытается записать в столбец и ищет свойство с именем APVendorId. Preet Sangha
Попробуйте установить профилировщик на SQL, а также увеличить регистрацию в NHibernate. Я обнаружил, что большинство проблем с NHiberate решаются с помощью подсказок из его удивительной регистрации (log4net). Посмотрите, что генерируется SQL и что ожидает NHiberate .. Preet Sangha
Это неseem ошибаться. Кажется, что отдельные репозитории работают и работают правильно. Сгенерированная схема кажется правильной. Jeremy Holovacs

Ваш Ответ

4   ответа
1

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

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

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

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

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

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

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

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

В моем случае мне нужно было сохранить родительский объект без дочернего элемента, поэтому добавление флага ReadOnly части отношения многие-к-одному работало так:stackoverflow.com/a/33253799/97471
14

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

Хм ... нет, глядя на то, что происходит через 6 лет, это все еще загадочно и ужасное сообщение об ошибке. Jeremy Holovacs
Это не загадочно - просто посмотрите на внутреннее исключение в информации, которую вы вставили.
Это, очевидно, то, что случилось. У меня была опечатка в другом доме, и я думаю, это повлияло на это. У меня не было бы проблемы с этим, за исключением того, что сообщение было настолько чертовски загадочным. Jeremy Holovacs
2

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

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

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

Отображение:

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

SQL:

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

ID column with constraint

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

Для решения проблемы необходимо указать столбец идентификатора какIDENTITY то есть

CREATE TABLE EMPLOYEE
(
    ID int NOT NULL IDENTITY(0, 1)
);
Вау, тоже пропустил, спасибо! знак равно
3

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

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

Похожие вопросы