26

I'm doing a fairly complex NHibernate transaction in a financial system, creating a payment, recording the ledger entries, checking to see if the payment is the total amount of an invoice, if so marking the invoice as paid in full, etc... lots of fun stuff. Naturally it has to happen inside a single transaction.

When I try to commit the change to the session, I get the following error:

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

Googling this did not turn up many record. Can someone tell me what this means and where I need to focus my debugging efforts?

UPDATE

Per request, here is the full error message:

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 Throwing NHibernate into DEBUG mode, I get a bunch of stuff like this:

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

It does not appear this is occurring when querying the database. I have a feeling it has problems with me creating a bunch of objects, relating them, and then trying to persist them, but that's a pure guess.

Preet Sangha
  • 64,563
  • 18
  • 145
  • 216
Jeremy Holovacs
  • 22,480
  • 33
  • 117
  • 254
  • What's the full exception, and is there an inner exception? – Preet Sangha Jun 03 '12 at 02:13
  • what about **Unable to resolve property: APVendorId** - does that give you a clue? Is the mapping wrong? The `NHUnitOfWork.Save()` is trying to write out to a column and is looking for a Property called APVendorId. – Preet Sangha Jun 03 '12 at 02:21
  • It doesn't *seem* to be wrong. The individual repositories seem to perform and build properly. The generated schema seems correct. – Jeremy Holovacs Jun 03 '12 at 02:26
  • 1
    Try putting a profiler on the SQL and also increasing the logging in NHibernate. I find that most issues with NHiberate are resolved using clues from it's amazing logging (log4net). See what SQL gets generated and what NHiberate is expecting.. – Preet Sangha Jun 03 '12 at 02:29
  • If that is the case I would reduce the size of the graph in the save until it works and work backwards. If that failed - I may even get the nhibernate source out. But at this point if all you are doing is creating a graph of objects then it might be time to simplify graph and try a little at a time. – Preet Sangha Jun 03 '12 at 02:47
  • What version of NHibernate is this? There are various issues in NH 2.0 with the Linq provider and various mapping types (ie component). – Michael Baker Jun 03 '12 at 07:36
  • This is 3.2, non-fluent. – Jeremy Holovacs Jun 03 '12 at 16:12

6 Answers6

21

It's likely that nhibernate is not showing the correct property of error, check the adjacent properties in the mapping file, looking for errors in relationship between data types from your database and data types from .net or repeated columns in properties... also check this link Fluent NHibernate - IndexOutOfRange

Community
  • 1
  • 1
  • 4
    This is apparently what happened. I had a typo in a different property and I guess it affected this one. I wouldn't have an issue with this except that the message was so freaking cryptic. – Jeremy Holovacs Jun 06 '12 at 13:20
  • 4
    It's not cryptic - just look at the inner exception in the info you pasted. – Piotr Szmyd Aug 15 '13 at 20:49
  • 9
    Um... no, looking at this going on 6 years later, it's still cryptic and a horrible error message. – Jeremy Holovacs Feb 28 '18 at 13:15
3

You should check CFAPTransaction mapping, It looks like you wanted to specify one Vendor for each transaction. In this case your mapping has to be like below code.

public CFAPTransactionMap()
{
  HasOne(x => x.Vendor).ForeignKey("VendorId").Cascade.All();
  ...
}
Arkadas Kilic
  • 2,416
  • 2
  • 20
  • 16
3

In my case it was a missing Identity Specification on the SQL-Server.

Simple object:

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:

Here is the ID column with the primary key constraint.

ID column with constraint

And here you can see the missing Identity Specification, which is causing the problem. Missing Identity Specification

To solve the problem, you have to specify the ID column as IDENTITY i.e.

CREATE TABLE EMPLOYEE
(
    ID int NOT NULL IDENTITY(0, 1)
);
COBRA.cH
  • 149
  • 1
  • 11
1

I encountered the same error. This is my sample mappings:

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

If I tried to persist/save this on my database by populating only the property intPersonID and making the objPerson null, this will trigger the dehydrating error on all your properties!

The reason I am just populating intPersonID is to prevent querying on the database to get the objPerson before saving to the database. Unfortunately, it will trigger an error, so I modified my mappings and corrected with this:

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

Or if I want to prevent querying on the database by getting the whole object, I will just use this mapping instead:

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

But combining them is not possible.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Willy David Jr
  • 8,604
  • 6
  • 46
  • 57
  • In my case I needed to persists the parent entity without the child, so adding the ReadOnly flag of the many-to-one part of the relation worked as in: https://stackoverflow.com/a/33253799/97471 – Gerardo Grignoli Mar 14 '19 at 18:37
0

In my case, the exception was accurately identifying the property that was the cause of the error. I had a many-to-one property that was lacking a cascade definition. "save-update" prevents the error:

<many-to-one name="FocusType" cascade="save-update"
    class="MyInfrastructure.FocusType, MyInfrastructure">
    <column name="FocusTypeId" sql-type="int" not-null="false" />
</many-to-one>
Al Lelopath
  • 6,448
  • 13
  • 82
  • 139
-1

a smart person once told me to add this to my mapping

.Length(int.MaxValue);
THess
  • 1,003
  • 1
  • 13
  • 21
alin
  • 39
  • 5