views:

46

answers:

2

Hi everyone, I've been battling with this issue for a couple of days now.

I have a couple of classes in a many-to-many relationship, configured like so:

<class name="Entry" table="Entries">
    <id name="Id" column="Id">
      <generator class="native" />
    </id>
    <timestamp name="LastUpdated" column="Entry_LastUpdated" generated="always" />
    ...
    <bag name="Sections" generic="true" table="EntrySections" inverse="false" cascade="none">
      <key column="EntrySection_EntryId" />
      <many-to-many column="EntrySection_SectionId" class="Blogs.BusinessLogic.Section, Blogs.BusinessLogic"/>
    </bag>
</class>

<class name="Section" table="Sections">
    <id name="Id" column="Id" unsaved-value="0">
      <generator class="native" />
    </id>
    <timestamp .../>
    ...
    <bag name="Entries" generic="true" table="EntrySections" inverse="false" cascade="none">
        <key column="EntrySection_SectionId" />
        <many-to-many column="EntrySection_EntryId" class="Blogs.BusinessLogic.Entry, Blogs.BusinessLogic"/>
    </bag>
</class>

It is configured in a way that I could delete, say, a Section object and its associations to any entries will be removed.

However, when I wish to only remove the associations, for example:

entry.Sections.Remove(section);

This is the only action I perform on this object. However, when the session flushes, the following StaleObjectStateException exception is thrown:

Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [Project.BusinessLogic.Entry#22]

I've been toying with the inverse and cascade values and googling for answers, but cannot find any solution. Neither inverse="true" nor cascade="all/all-delete-orphan" did the trick.
Is this a problem related to the many-to-many relationship, or am I looking in the wrong direction?
Are my classes mapped incorrectly?

Edit

Could this be an issue resulting from the way NHibernate works with the and the DateTime struct?

A: 

Don't you have to mark one end of the association as 'inverse=true' and the other as 'inverse=false' ? By doing so, you define the 'owner' of the association.

Frederik Gheysels
I think that doesn't make any difference in this particular case. If I'm not mistaken, it's mostly for helping NHibernate decide how to create the association. My problem seems to be unrelated to that.
GeReV
A: 

Apparently my assumption was correct. The problem was caused by the <timestamp/>.

There seems to be some problem in the way I designed and mapped it, or perhaps an issue with NHibernate itself.
The timestamp was mapped as:

<timestamp name="LastUpdated" column="Entry_LastUpdated" generated="always" />

The field type in the database (MSSQL 2005 server) was datetime, with a matching System.DateTime property on the object. This did not work.

I've tried a few other configurations, as described here by Ayende Rahien, but couldn't get it to work either.
Eventually, I removed the <timestamp/> and will result to using code to manage modification dates while adding a numeric version field where needed.

If anyone could give any information on version management with timestamps in NHibernate it would be greatly appreciated.

GeReV