views:

65

answers:

2

I'm using Fluent NHibernate and the setup I have is as follows:

An Address object, which is a simple list of address fields.

A Company object which has two references to address objects, MainAddress, InvoiceAddress.

The problem I'm having is that on occasion both MainAddress and InvoiceAddress may refer to the same record in the Address table.

Addresses are looked up by searching, using something along the lines of:

ICriteria c = session.CreateCriteria(typeof(Address))
            .Add(Example.Create(address).ExcludeNone());

Because each Address is selected seperately, this leads to two instances of the same record, which causes NHibernate to puke when trying to save the Company object.

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

What's the best way to work around this?

Thanks!

+1  A: 

You should use NHibernate's Merge.

merge():

  • if there is a persistent instance with the same identifier currently associated with the session, copy the state of the given object onto the persistent instance
  • if there is no persistent instance currently associated with the session, try to load it from the database, or create a new persistent instance
  • the persistent instance is returned
  • the given instance does not become associated with the session, it remains detached

It's the same as SaveOrUpdateCopy, but that command's apparently deprecated:

I think SaveOrUpdateCopy is something that has exited in NHibernate for all time and Merge is something added in 2.1 (clearly something ported from the hibernate). Anyway I am very glad that NHibernate has this ability because writing and handling the merge operation manually is very boring code to write!

Rafael Belliard
This did the trick, but I think that Diego is correct that it was caused by doing each query in a separate session. Will look into rectifying that...
RSlaughter
+2  A: 

Unless you are selecting in different sessions and then mixing them (which is incorrect), NHibernate's default behavior is to retrieve the same instance for the same row, no matter how many times you query.

Make sure you're using a single session.

Diego Mijelshon