2012-07-14 22 views
8

Recibo el error Error al deshidratar el valor de propiedad durante el proceso de confirmación durante la actualización. He buscado y parece similar a NHibernate: Error dehydrating property - What the heck is this? la única diferencia de que en la pregunta REFIERE NHibernate se quejaba de No se puede resolver la propiedadNHibernate - Error al deshidratar el valor de la propiedad

valor para IssuingOffice ya existe en la base de datos por lo que no puede ser un problema en incluir una registro no guardado

El siguiente es el error de detalle.

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) 

Mapeo para 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> 

Esquema para IssuingOffice

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

Mapeo para 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" /> 

Esquema para 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) 
) 

traté de desajustes de tipo de datos o propiedades repetidas, pero no lo encontró.

Cualquier ayuda será apreciada.

Respuesta

7

Si se echa un vistazo a su excepción con más cuidado, verá este 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

Básicamente, parece que usted está tratando de salvar el IssuingOffice que contiene uno o más StickerInvoice no guardado. Debe configurar el mapeo de bolsa cascading option en IssuingOffice.

<bag name="IssuedStickers" table="StickerInvoice" 
    generic="true" inverse="true" cascade="save-update"> 
    <key column="StickerIssuingOfficeId" /> 
    <one-to-many class="StickerInvoice"/> 
</bag> 
+0

IssuingOffice ya existe en la base de datos y por lo tanto no requiere de ahorro o actualización. Solo quiero actualizar los datos existentes en StickerInvoice sin afectar IssuingOffice. En estos casos ¿realmente necesito una cascada? – kagundajm

+0

Entonces probablemente esté utilizando una instancia transitoria de StickerInvoice, tal vez cargada en otra sesión. –

+0

Investigando su último comentario, me di cuenta de que la versión de IssuingOffice se estableció inicialmente en 0 durante la inicialización de datos. Cambiar el valor a 1 resolvió el problema. Gracias por su ayuda – kagundajm

3

resolví esta excepción mediante el establecimiento de la bandera de sólo lectura de la parte de muchos-a-uno de la relación:

References(x => x.Parent).ReadOnly(); 
+0

Me pregunto por qué las muestras no se refieren a esta solución simple. He perdido alrededor de 2-3 días buscando esta solución simple. – shankbond

Cuestiones relacionadas