Hi, I've been tracking a strange problem all day and I'm not sure where to start to go from now. I'm using the latest NH 1.0.1 with a SQL 2000. The problem is strange because sometimes under the very same circumstances the bug does not show up. I'll try to explain as much as I can.
The bug appears in an async process. This process is asigned the lowest thread priority. The process reads some files and creates entites as it goes along. The process goes on adding entites (PlazoFijo) to a Bag. At some point it finishes and sees that there was an error so it issues (before commiting the transaction) a .Clear() on the collection. Then I get then following exception:
2005-12-26 21:04:14,760 [320] ERROR - An operation failed due to stale data
NHibernate.StaleObjectStateException: Row was updated or deleted by another transaction for SAFJP.SICI.Model.Carteras.Custodias.PlazoFijo instance with identifier: -1
I debug the code to NH up to where it issues a delete for the entity with an ID= -1 and does a Check(). This strikes me as odd, why did NH marked this particular entity for delete with a SQL statement since I have set the unsaved-value = -1 on the Id. Also, how is it possible that some entities in the bag have an Id != -1 and the last dont.
Worst is that some times under the same circimstances the bug does not appear. I'm suspecting the Cache could be involved but not sure how.
Thanks for any help, I'm kinda desperate at this point
Following are the HBMs. Sorry its in spanish (client request :( ). The bug appears to be after adding PlazoFijo to UploadCustodia. UploadCustodia is a hierarchy mapped with table-per-hierarchy and PlazoFijo is mapped as a table-per-class.
Note: I've debugged NH a couple of times, so any help on where to look at the source code. Maybe it is a bug after all....
Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping
xmlns="urn:nhibernate-mapping-2.0"
namespace="SAFJP.SICI.Model.Common.Uploads"
assembly="SAFJP.SICI.Model.Common"
default-access="field">
<class
name="Upload"
table="T_Upload"
proxy="Upload">
<id
name="mId"
column="upload_ID"
type="Int32"
unsaved-value="-1">
<generator class="native"/>
</id>
<discriminator
column="tipoUpload_Class"
type="String"
length="15"
/>
<property
name="mFechaUpload"
column="D_upload"
type="DateTime"
/>
<property
name="mFechaDatos"
column="D_datos"
type="DateTime"
/>
<many-to-one
name="mEstado"
column="estadoUpload_ID"
class="SAFJP.SICI.Model.Common.Uploads.EstadosUploads.EstadoUpload"
/>
<many-to-one
name="mUsuario"
column="usuarioSICI_ID"
class="SAFJP.SICI.Security.UsuarioSICI, SAFJP.SICI.Security"
/>
<bag
name="mErrores"
order-by="error_ID"
cascade="all-delete-orphan"
lazy="true">
<key column="upload_ID" />
<one-to-many class="ErrorUpload" />
</bag>
<!-- ========================== -->
<!-- Subclase UploadAFIP -->
<!-- ========================== -->
<subclass
name="SAFJP.SICI.Model.Carteras.AFIP.UploadAFIP,SAFJP.SICI.Model.Carteras"
proxy="SAFJP.SICI.Model.Carteras.AFIP.UploadAFIP,SAFJP.SICI.Model.Carteras"
discriminator-value="UP_AFIP">
<bag
name="mRecaudaciones"
cascade="all-delete-orphan"
lazy="true">
<key column="uploadAFIP_ID" />
<one-to-many class="SAFJP.SICI.Model.Carteras.AFIP.RecaudacionAFJP,SAFJP.SICI.Model.Carteras"/>
</bag>
</subclass>
<!-- ========================== -->
<!-- Subclase UploadCotizacion -->
<!-- ========================== -->
<subclass
name="SAFJP.SICI.Model.Carteras.Cotizaciones.UploadCotizacion,SAFJP.SICI.Model.Carteras"
proxy="SAFJP.SICI.Model.Carteras.Cotizaciones.UploadCotizacion,SAFJP.SICI.Model.Carteras"
discriminator-value="UP_COTIZACION">
<bag
name="mCotizaciones"
cascade="all-delete-orphan"
lazy="true">
<key column="uploadCotizacion_ID" />
<one-to-many class="SAFJP.SICI.Model.RecursosFinancieros.Cotizaciones.Cotizacion,SAFJP.SICI.Model.RecursosFinancieros"/>
</bag>
</subclass>
<!-- ========================== -->
<!-- Subclase UploadCustodia -->
<!-- ========================== -->
<subclass
name="SAFJP.SICI.Model.Carteras.Custodias.UploadCustodia,SAFJP.SICI.Model.Carteras"
proxy="SAFJP.SICI.Model.Carteras.Custodias.UploadCustodia,SAFJP.SICI.Model.Carteras"
discriminator-value="UP_CUSTODIA">
<many-to-one
name="mCustodia"
column="custodia_ID"
class="SAFJP.SICI.Model.RecursosFinancieros.Custodia, SAFJP.SICI.Model.RecursosFinancieros"
/>
<bag
name="mPlazosFijos"
order-by="elementoCustodiado_ID"
cascade="all-delete-orphan"
lazy="true"
inverse="true">
<key column="uploadCustodia_ID" />
<one-to-many class="SAFJP.SICI.Model.Carteras.Custodias.PlazoFijo,SAFJP.SICI.Model.Carteras"/>
</bag>
<bag
name="mInversiones"
order-by="elementoCustodiado_ID"
cascade="all-delete-orphan"
lazy="true">
<key column="uploadCustodia_ID" />
<one-to-many class="SAFJP.SICI.Model.Carteras.Custodias.Inversion,SAFJP.SICI.Model.Carteras"/>
</bag>
<bag
name="mCuentasCorrientes"
order-by="elementoCustodiado_ID"
cascade="all-delete-orphan"
lazy="true">
<key column="uploadCustodia_ID" />
<one-to-many class="SAFJP.SICI.Model.Carteras.Custodias.CuentaCorrienteCustodia,SAFJP.SICI.Model.Carteras"/>
</bag>
</subclass>
</class>
</hibernate-mapping>
Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping
xmlns="urn:nhibernate-mapping-2.0"
namespace="SAFJP.SICI.Model.Carteras.Custodias"
assembly="SAFJP.SICI.Model.Carteras"
default-access="field">
<class
name="ElementoCustodiado"
table="T_Elemento_Custodiado">
<id
name="mId"
column="elementoCustodiado_ID"
type="Int32"
unsaved-value="-1">
<generator class="native" />
</id>
<property
name="mCodigoAFJP"
column="codigoAfjp"
type="String"
length="4"
/>
<many-to-one
name="mAfjp"
column="AFJP_ID"
class="SAFJP.SICI.Model.RecursosFinancieros.AFJP,SAFJP.SICI.Model.RecursosFinancieros"
/>
<!-- ================================ -->
<!-- Subclass PlazoFijo -->
<!-- ================================ -->
<joined-subclass
name="PlazoFijo"
table="T_Plazo_Fijo">
<key column="elementoCustodiado_ID" />
<property
name="mCodigoBanco"
column="codigoBanco"
type="Int32"
/>
<property
name="mTipoDeposito"
column="tipoDeposito"
type="String"
/>
<property
name="mNumeroDeposito"
column="N_deposito"
type="String"
/>
<property
name="mFechaEmision"
column="D_emision"
type="DateTime"
/>
<property
name="mFechaVencimiento"
column="D_vencimiento"
type="DateTime"
/>
<property
name="mMontoInicial"
type="SAFJP.SICI.Model.NHUserTypes.DineroUserType, SAFJP.SICI.Model.NHUserTypes">
<column name="A_montoInicial" />
<column name="codigoMonedaMontoInicial_ID" />
</property>
<many-to-one
name="mTipoCartera"
class="SAFJP.SICI.Model.Carteras.TipoCartera"
column="codigoCartera"
/>
<many-to-one
name="mUpload"
column="uploadCustodia_ID"
class="SAFJP.SICI.Model.Carteras.Custodias.UploadCustodia"
/>
</joined-subclass>
<!-- ================================ -->
<!-- Subclass Inversion -->
<!-- ================================ -->
<joined-subclass
name="Inversion"
table="T_Inversion">
<key column="elementoCustodiado_ID" />
<property
name="mCodigoCarteraInformado"
column="codigoCarteraInformado"
type="string"
length="2"
/>
<many-to-one
name="mTipoCartera"
class="SAFJP.SICI.Model.Carteras.TipoCartera"
column="codigoCartera"
/>
<property
name="mCodigoSAFJP"
column="codigoSAFJP"
type="String"
length="20"
/>
<property
name="mCodigoISIN"
column="codigoISIN"
type="String"
length="20"
/>
<property
name="mCantidadNominal"
column="Q_nominal"
type="Decimal"
/>
<many-to-one
name="mUpload"
column="uploadCustodia_ID"
class="SAFJP.SICI.Model.Carteras.Custodias.UploadCustodia"
/>
</joined-subclass>
<!-- ================================ -->
<!-- Subclass Inversion -->
<!-- ================================ -->
<joined-subclass
name="CuentaCorrienteCustodia"
table="T_Cuenta_Corriente_Custodia">
<key column="elementoCustodiado_ID" />
<property
name="mCodigoBanco"
column="codigoBanco"
type="Int32"
/>
<property
name="mTipoGeneralCartera"
column="tipoGeneralCartera"
/>
<property
name="mNumeroCuenta"
column="N_cuenta"
type="String"
/>
<property
name="mSaldo"
type="SAFJP.SICI.Model.NHUserTypes.DineroUserType, SAFJP.SICI.Model.NHUserTypes">
<column name="A_saldo" />
<column name="codigoMonedaSaldo_ID" />
</property>
<many-to-one
name="mUpload"
column="uploadCustodia_ID"
class="SAFJP.SICI.Model.Carteras.Custodias.UploadCustodia"
/>
</joined-subclass>
</class>
</hibernate-mapping>