Hi,
I have an issue when the following features are combined:
<timestamp generated="always">
cascade="all-delete-orphan"
For various reasons (legacy support, multiple concurrent NHibernate
clients, support for non-NHibernate clients) I've used timestamp
generated="always" along with postgres triggers to implement
modification dates / concurrency checking. This is working well in
most cases with the exception of cascaded deletes.
I've got a pretty standard "Customer" owns multiple "IdentityItems"
unidirectional relationship. Mapping snippets below:
<class name="Customer" table="CUSTOMER" >
<id name="id" column="ID" type="string" length="32" unsaved-
value="null" >
<generator class="uuid.hex" />
</id>
<timestamp name="modified" column="modified" generated="always"
/>
<bag name="identification" cascade="all-delete-orphan"
lazy="true" order-by="TYPE_ ASC">
<key column="CUSTOMER_ID" />
<one-to-many class="IdentificationItem" />
</bag>
<!-- more properties here.... -->
</class>
<class name="IdentificationItem table="IDENTITY_ITEM" >
<id name="id" column="ID" type="string" length="32" unsaved-
value="null" >
<generator class="uuid.hex" />
</id>
<timestamp name="modified" column="modified" generated="always"
/>
<!-- more properties here.... -->
</class>
This all works as expected until I try to issue a cascaded delete by
removing an item from customer.identification and then flushing.
customer.identification.remove(item);
NHSession.flush();
Throws this error:
Row was updated or deleted by another transaction (or unsaved-value
mapping was incorrect):
[globalmoneyline.models.IdentificationItem#289002285f344cd684940e119974563f]
Setting log4net to debug shows exactly why this occurs.
NHibernate fires two queries:
UPDATE IDENTITY_ITEM SET CUSTOMER_ID = null WHERE CUSTOMER_ID = :p0
AND ID = :p1;:p0 = '1a6ccf9caa0b4e9a85a51aeec2762e94' [Type: String
(0)], :p1 = '289002285f344cd684940e119974563f' [Type: String (0)]
DELETE FROM IDENTITY_ITEM WHERE ID = :p0 AND modified = :p1;:p0 =
'289002285f344cd684940e119974563f' [Type: String (0)], :p1 =
14/12/2011 2:34:17 PM [Type: DateTime (0)]
The first query sets the refererring id to null. Unfortunately this
also causes the "generated" database trigger timestamp to update the
modified field. So when the second query fires, the row has changed
and a StaleObjectException is raised.
Any suggestions / workarounds will be gratefully received!
--
You received this message because you are subscribed to the Google Groups
"nhusers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/nhusers?hl=en.