tags:

views:

778

answers:

2

I have a class A containing a list of B mapped like that

<class name="A" table="CLASS_A">
    ...
    <idbag name="ListOfB"
           table="CLASS_A_CLASS_B"
           cascade="save-update">
      <collection-id column="ID" type="Guid">   <!-- surrogate key -->
        <generator class="guid.comb"/>
      </collection-id>
      <key column="ID_A"/>
      <many-to-many column="ID_B" class="B"/>
    </idbag>
</class>

On the DB side, there's a many-to-many join CLASS_A_CLASS_B table between CLASS_A & CLASS_B tables and it's got an ID surrogate key. The many-to-many relation is not mapped in the object model of class B.

Initially, let's say I have object X1 and X2 in ListOfB. If I remove X2 and insert X3, I noticed that NHibernate will do an update of the foreign key pointing to X2 to make it point to X3.

This is a fine optimization.

For my purpose however, I would like to trick NHibernate into doing a delete followed by a new insertion in the M2M join table (delete row for X2, insert new row for X3). I want that since these tables are replicated to another instance of our application and we show a diff of insert/update/delete to the user.

In this particular case, the use case is really "I removed X2 and added X3", so I'd like the diff the show that fact (instead of an update). I understand this behavior is suboptimal but it does not matter in this case.

Any way to trick NHibernate into doing that ?

+1  A: 

One suboptimal way would to remove X2 flush the session, then add X3. I believe nHibernate would treat that as two seperate actions and not optimize them.

You could also try and specify the: <sql-delete></sql-delete> action in the mapping file.

JoshBerke
I didn't know that NHibernate would optimize one delete followed by an insert with one update instead. Neat. I think flushing the session is also the way to go. Flushing tells NHibernate to persist all the changes up to that point (the delete) at which point you could do your insert. Also note that you can do multiple flushes inside of a transaction.
Stuart Childs
I didn't either and am still skeptical but if it does this would solve the issue.
JoshBerke
A: 

Thanks, I did not think about the flush. It definitely should work fine.

Later yesterday, I've been unable to trigger that behavior again...