a different object with the same identifier value was already associated with the session

4,213 views
Skip to first unread message

DannyT

unread,
Jul 10, 2008, 1:00:00 PM7/10/08
to nhu...@googlegroups.com
On my webform I have a collection of categories displayed as a checkbox list.
The user selects the chosen categories and they get associated to a document.

This is setup as a bag:

<bag name="RelatedCategories" table="tbl_document_category">
      <key column="document_id" />
      <many-to-many column="category_id" class="Category" />
</bag>

Every time the page is saved I return a list of category Id's to my presenter which then iterates all available categories and puts them in the Document's RelatedCategory collection.

If the document has no previous associated categories this works fine, however when trying to add or change the selected categories this is causing the error:
a different object with the same identifier value was already associated with the session
Obviously because i'm adding the same category as was already selected.

When the Document is saved I get the Document from the database by its ID (or create a new one), update all the values then flush it back. Is this the wrong approach?

What should I be doing in order to avoid this?

--
http://danny-t.co.uk

DannyT

unread,
Jul 11, 2008, 11:14:14 AM7/11/08
to nhu...@googlegroups.com
In case that doesn't make sense, all I'm asking really is what is the correct process to acheive:

1 - load by id
2 - repopulate a collection property
3 - SaveOrUpdate

My actual implementation is slightly different to the below scenario I described trying to simplify things. I actually have a Document with a bag of RelatedDocuments (same type).

My Database tables are:

tbl_document: document_id,  title, date
tbl_document_related:  related_id, parent_id, child_id


Where both parent_id and child_id join back to tbl_document.
and my mapping:

<class name="Document, domain" table="tbl_document">
    <id name="Id" column="document_id">
      <generator class="identity" />
    </id>
    <property name="Title" column="title" />
    <bag name="RelatedDocuments" table="tbl_document_related" cascade="all">
      <key column="parent_id" />
      <many-to-many column="child_id" class="Document, domain" />
    </bag>
</class>

I feel like i'm going round in circles with this, any help greatly appreciated :S

Dan


2008/7/10 DannyT <danm...@googlemail.com>:



--
http://danny-t.co.uk

James Kovacs

unread,
Jul 16, 2008, 2:34:11 PM7/16/08
to nhu...@googlegroups.com
It sounds like you have multiple Document objects representing the same Document entity. This is likely due to "new-ing" up the objects during a postback. Your new objects are not associated with an NHibernate session and you want to attach the objects to a session so that you can persist changes. For example:

Doc1 -> Doc2 -> Doc1'

where Doc1 and Doc1' are different objects, but have the same identifier.

You have a few potential solutions.

#1 Create an identity map to use when re-creating the objects. Basically this is a hashtable of ID vs. object. Before creating each document object, check if you've already created it. If so, use the same physical object.

#2 Collect up all the IDs, start a NH session, load the Document objects using NH, update the Document objects with the posted back data, commit the transaction, then close the session.

#3 Use ISession.SaveOrUpdateCopy() to get a new copy of your object that is associated with the ISession. Use the returned instance to construct your object graph and then persist any changes.

There are other ways using ISession.Update() with select-before-update in the class mapping or ISession.Lock(obj, LockMode.None).

HTH,
James
--
James Kovacs, B.Sc., M.Sc., MCSD, MCT
Microsoft MVP - C# Architecture
http://www.jameskovacs.com
jko...@post.harvard.edu
403-397-3177 (mobile)

Tommaso Caldarola

unread,
Jul 17, 2008, 3:57:30 AM7/17/08
to nhusers
Maybe loading document and then trying to add/remove categories the
session used is the same?
I had in the past the same problem, I did fix it using

UoW.start
load document
UoW.close

UoW.start
add/remove categories
UoW.close
Reply all
Reply to author
Forward
0 new messages