views:

46

answers:

1

Backgroud: I'm using NHibernate for my model layer, and I have a HTTP module taking care of instantiating the session at the beginning of each request and cleaning it up at the end of each request (i.e. Session Per Request). In this case, I have two object types:

ParentItem - an object with a bunch of properties and a collection of ChildItems.
ChildItem - an object with properties including a DateTime (EffectiveDate) and an unenforced FK pointing to a completely different database. The ChildItem class contains a reference back to the parent as well (many-to-one)

While the ParentItem has multiple ChildItems in its collection, I'm only generally interested in the latest ChildItem in the collection.

Desire: Want a databound control (GridView or ListView, I don't care which) that allows me to Add/Edit/Delete ParentItems from my datasource. I also want to have the ability to set a new "latest" ChildItem as part of the edit/update.

Issue: I can't seem to access the underlying DataItem from the GridView/ListView in the OnItemUpdating handler (which isn't unexpected, since the data is now in the viewstate). What I thought I could do would be to load a ParentItem from my session using the ID from the databound control, create a new ChildItem, add it to the ParentItem, and then save the ParentItem. Since NHibernate caches the data, the load should give me a copy from cache (no roundtrip to the DB) and I'd either be doing this before the ParentItem was saved back (thus no changes committed to ParentItem, just to ChildItem) or after (thus the cached version is still the same, and my new object will match the updated version). What I get when I do this (for ParentItemID=1):

a different object with the same identifier value was already associated 
with the session: 1, of entity: NameSpace.ParentItem

on the line:

Session.SaveOrUpdate(parentItemInstance);

I'm guessing this has to do with the fact my ObjectDataSource loaded this ParentItem already in order to update it, but I'm not sure where to go from here.

+1  A: 

You problem is probably session related. Are you creating and closing NHibernate session per-request?

The problem is "What I thought I could do would be to load a ParentItem from my session using the ID from the databound control". You seems to save an object loaded from one session and save it in another session.

You should use session.Merge to save your object from another session into you current session. You find an excellent article about the difference between session.SaveOrUpdate and session.Merge here: http://stackoverflow.com/questions/170962/nhibernate-difference-between-session-merge-and-session-saveorupdate

Andreas Paulsson
I had tried to do it with session.Merge, but had a different (but similar) problem. I'll go back and play with it again to see if I can get it to work (or remember why it didn't)
Kendrick
The problem is that when the ObjectDataSource saves a ParentItem object with the specified ID, probably without loading it first, a ParentItem object with that ID has already been created when my custom routine saves the ChildItem. If I do it in the other direction, merge might work. What I did discover is that if I save my ChildItem and then use Session.Evict(ParentItem) at the end of my OnUpdating handler, my session is now clean and ready to save the updated ParentItem. I'm not sure the SQL generated here is remotely efficient, but that's something to deal with another day...
Kendrick
Note: your answer isn't what I was looking for, but you get the checkmark for showing up and pushing me in the right direction :-)
Kendrick