*Current Approach*

In an ASP.NET <http://asp.net/> web forms app (using Spring.NET and 
NHibernate) we have an aggregate root (*Person*) whose details are captured 
across a number of screens/pages. The *Person* entity exists prior to 
entering into this workflow, and all changes made to the *Person* object 
graph are atomic, and so should only be flushed to database upon submission 
of the final screen.

To achieve this, we load the *Person* (lazily) from the database using 
NHibernate 3.2 the first time into the first page, and thereafter we load 
and save the serialized *Person* object graph to a HTTP Session variable as 
we page through the process.

After retrieving the *Person* out of the HTTP Session, it is in a detached 
state from the current NHibernate session, so we re-attach by invoking the *
Update()* method on the current session, like so:

var sessionPerson = Session[PersonSessionName] as Person;var currentSession = 
SessionFactory.GetCurrentSession();
currentSession.Update(sessionPerson);

Note: Using *Lock()* threw an exception, advising that the “reassociated 
object has dirty collection”.

When reattached, we can traverse through the object graph as expected, 
pulling data from the database for child entities which had not yet been 
loaded into memory.

*Subset of Mapping Files*

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" auto-import="false" 
assembly="Domain" namespace=" TestApp.Domain">
  <class name="Person" table="Person">
    <id name="Id">
      <generator class="TestApp.CustomNHibernateHiLoGenerator, TestApp.Core" />
    </id>
    <property name="Name" not-null="false" />

    <bag name="PersonCountries" access="field.camelcase-underscore" 
cascade="all-delete-orphan">
      <key column="PersonId" foreign-key="FK_ PersonCountry_Person" 
not-null="true" />
      <one-to-many class="PersonCountry" />
    </bag>
  </class>

  <class name="Country" table="Country">
    <id name="Id">
      <generator class="TestApp.CustomNHibernateHiLoGenerator, TestApp.Core" />
    </id>
    ... No back reference to Person
  </class></hibernate-mapping>

*Domain*

public class PersonCountry : Entity, ICloneable{
    // No properties of note}
public class Person : Entity, ICloneable{
    public virtual string Name { get; set; }
    public virtual IEnumerable<PersonCountry> PersonCountries { get; set; }
    ... 
    // More Properties}

*Flushing changes to database*

.. // Code-behindPricingService.Save(ProductContext.Pricing, forceMerge: true); 
           

public class PricingService : IPricingService{
   [Transaction]  // Spring.NET transaction
   public Pricing Save(Pricing pricing, bool forceMerge = false)
   {            
      if(forceMerge)
      {
         CurrentSession.Merge(entity);
      }
      else
      {
         CurrentSession.SaveOrUpdate(entity);
      }
   }}

When it comes time to flush all changes to the database, provided we only 
change *Name*, the change works as expected. However, adding a new *Country* 
item 
to *Person* causes the cascading of the *Merge()* on one-to-many 
relationships to fail with the following exception (oddly, removing a *
Country* works fine).

NHibernate.StaleStateException: Batch update returned unexpected row count from 
update; actual row count: 0; Expected: 1

Any help would be greatly appreciated.

-- 
You received this message because you are subscribed to the Google Groups 
"nhusers" group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/nhusers/-/9OCdKu2GS9gJ.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/nhusers?hl=en.

Reply via email to