2
votes

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?

2
Can you include your <id> section from each mapping? Are you using <version> at all?Shane Courtrille
@ShaneC: I've added the <id> section. I'm using a timestamp mapping instead of version.GeReV

2 Answers

1
votes

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.

0
votes

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.