Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NHibernate - Error dehydrating property value

Tags:

c#

nhibernate

I am getting the error Error dehydrating property value for while committing during update. I have searched and it looks similar to NHibernate: Error dehydrating property - What the heck is this? the only difference being that in the refered question NHibernate was complaining of Unable to resolve property

Value for IssuingOffice is already existing in the database so it cannot be an issue of referencing an un-saved record

The following is the detailed error.

Test 'Tests.Services.StickerInvoiceServiceTests.update_sticker_info_succeeds' failed:
NHibernate.PropertyValueException : Error dehydrating property value for
Model.StickerInvoice.StickerIssuingOffice
----> NHibernate.TransientObjectException : object references an unsaved transient 
instance - save the transient instance before flushing or set cascade action for the property to something that would make it autosave. Type: Model.IssuingOffice, Entity: Model.IssuingOffice
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.Update(Object id, Object[] fields, Object[] oldFields, Object rowId, Boolean[] includeProperty, Int32 j, Object oldVersion, Object obj, SqlCommandInfo sql, ISessionImplementor session)
at NHibernate.Persister.Entity.AbstractEntityPersister.UpdateOrInsert(Object id, Object[] fields, Object[] oldFields, Object rowId, Boolean[] includeProperty, Int32 j, Object oldVersion, Object obj, SqlCommandInfo sql, ISessionImplementor session)
at NHibernate.Persister.Entity.AbstractEntityPersister.Update(Object id, Object[] fields, Int32[] dirtyFields, Boolean hasDirtyCollection, Object[] oldFields, Object oldVersion, Object obj, Object rowId, ISessionImplementor session)
at NHibernate.Action.EntityUpdateAction.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()
UnitOfWork.cs(39,0): at NhRepository.UnitOfWork.Commit()
StickerInvoiceService.cs(73,0): at Services.StickerInvoiceService.UpdateStickerInfo(StickerInvoice entity, IEnumerable`1& brokenRules)
Services\StickerInvoiceServiceTests.cs(131,0): at Tests.Services.StickerInvoiceServiceTests.update_sticker_info_succeeds()
--TransientObjectException
at NHibernate.Engine.ForeignKeys.GetEntityIdentifierIfNotUnsaved(String entityName, Object entity, ISessionImplementor session)
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)

Mapping for IssuingOffice

<class name="IssuingOffice" table="IssuingOffice">
<id name="Id">
  <generator class ="hilo">
    <param name ="table">IdGenerator</param>
    <param name ="column">NextHigh</param>
    <param name ="max_lo">2</param>
    <param name ="where">TableKey = 'IssuingOffice'</param>
  </generator>
</id>
<version name="Version" column="Version" />
<property name ="Name" length="150" not-null="true" unique="true" />
<bag name ="IssuedStickers" table ="StickerInvoice" generic="true" inverse="true">
  <key column ="StickerIssuingOfficeId" />
  <one-to-many class ="StickerInvoice"/>
</bag>

Schema for IssuingOffice

CREATE TABLE IssuingOffice(
 Id   int  NOT NULL,
 Name   nvarchar (150) NOT NULL,
 Version   int  NOT NULL,
   CONSTRAINT  PK_IssuingOffice  PRIMARY KEY ( Id  ASC )
 ) 

Mapping for StickerInvoice

<class name="StickerInvoice" table="StickerInvoice">
<id name="Id">
  <generator class ="hilo">
    <param name ="table">IdGenerator</param>
    <param name ="column">NextHigh</param>
    <param name ="max_lo">5</param>
    <param name ="where">TableKey = 'StickerInvoice'</param>
  </generator>
</id>
<version name ="Version" />
<property name ="RefNo" length="50" not-null="true" />
<property name ="Period" not-null="true" />
<property name ="Amount" not-null="true"/>
<property name ="DueDate" not-null="true"/>
<property name ="Penalty" not-null="true"/>
<property name ="InvoiceNo" length="50"/>
<property name ="DateIssued" />
<property name ="ReceiptNo" length="50" />
<property name ="DatePaid" />
<property name ="StickerNo" length="50" />
<many-to-one name ="Vehicle" class="Vehicle" column ="VehicleId" />
<many-to-one name ="StickerIssuedBy" class="User" column ="StickerIssuedById" />
<many-to-one name ="StickerIssuingOffice" class="IssuingOffice" column ="StickerIssuingOfficeId" />

Schema for StickerInvoice

CREATE TABLE StickerInvoice(
    Id int NOT NULL,
RefNo nvarchar(50) NOT NULL,
VehicleId int NOT NULL,
DateIssued datetime NOT NULL,
Period datetime NOT NULL,
Amount decimal(18, 0) NOT NULL,
DueDate datetime NOT NULL,
Penalty decimal(18, 0) NOT NULL,
InvoiceNo nvarchar(50) NULL,
ReceiptNo nvarchar(50) NULL,
DatePaid datetime NULL,
StickerNo nvarchar(50) NULL,
StickerIssuedById int NULL,
StickerIssuingOfficeId int NULL,
Version int NOT NULL,
  CONSTRAINT PK_StickerInvoice PRIMARY KEY ( Id ASC )
)  

I tried for datatype mismatches or repeated properties but found none.

Any assistance will be appreciated.

like image 661
kagundajm Avatar asked Jul 14 '12 08:07

kagundajm


2 Answers

If you take a look at your exception more carefully, you'll see this error:

NHibernate.TransientObjectException : object references an unsaved transient instance - save the transient instance before flushing or set cascade action for the property to something that would make it autosave. Type: Model.IssuingOffice, Entity: Model.IssuingOffice

Basically, looks like you are trying to save the IssuingOffice containing one or more unsaved StickerInvoice. You need to set the cascading option to IssuingOffice bag mapping.

<bag name="IssuedStickers" table="StickerInvoice" 
     generic="true" inverse="true" cascade="save-update">
  <key column="StickerIssuingOfficeId" />
  <one-to-many class="StickerInvoice"/>
</bag>
like image 59
Miroslav Popovic Avatar answered Oct 23 '22 19:10

Miroslav Popovic


I resolved this exception by setting ReadOnly flag of the many-to-one part of the relation:

References(x => x.Parent).ReadOnly();
like image 26
Vedran Avatar answered Oct 23 '22 20:10

Vedran