Hi All, I've got a patent-child (Customer being the parent and Address being the child) setup in NHibernate setup with a one-to-many relationship. I have all-delete-orphan cascade and all works well except.
1. When I load a customer (with Addresses) 2. Add an address, modify an address and remove and address
If I do step 1 and 2 within the same session: - My customer is updated (even if no properties on it are modified, but I guess the change to teh Addresses collection triggers this) - The new address is inserted into the db - The removed address is deleted from the db
Which is PERFECT...my problem occurs when I do step 1 and 2 in two different sessions, in that case, all the above happens in addition to: - All unmodified addresses are also updated
This is a big problem for me as I plan to have lots of objects on my customer and I need updates to be generated only when necessary.
My entity configuration is as follows:
======================= Customer.hbm.xml ======================= <?xml version="1.0" encoding="utf-8" ?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="DomainProject" namespace="DomainProject.Domain"> <class name="Customer"> <id name="Id"> <generator class="identity" /> </id> <version name="Version" access="backfield"/> <property name="Name" /> <property name="Category" /> <property name="Active" /> <property name="CreatedBy" /> <property name="UpdatedBy" /> <property name="CreatedDate" /> <property name="UpdatedDate" />
<bag name="Addresses" lazy="false" inverse="true" cascade="all-delete-orphan"> <key column="CustomerId"/> <one-to-many class="Address"/> </bag> </class> </hibernate-mapping>
======================= Address.hbm.xml ======================= <?xml version="1.0" encoding="utf-8" ?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="DomainProject" namespace="DomainProject.Domain"> <class name="Address"> <id name="Id"> <generator class="identity" /> </id> <version name="Version" access="backfield"/> <property name="CustomerId" /> <property name="Street" /> <property name="Suburb" /> <property name="City" /> <property name="Active" /> <property name="CreatedBy" /> <property name="UpdatedBy" /> <property name="CreatedDate" /> <property name="UpdatedDate" /> </class> </hibernate-mapping>
The thing that puzzled me is that NHibernate figures out the changes to my Address collection and it does delete orphaned records, I spend a lot of time debugging through and I can see it's caching them in "AbstractEntityPersister" what I can't figure our is why It's only making the linkage for collections and not for entities as well. Surely this info can be relinked!
Otherwise...
I've tried re-selecting the customer and used both Merge and Lock commands to set the session up correctly but got the following errors:
Calling Merge throws or Lock throw: a different object with the same identifier value was already associated with the session: 8, of entity: DomainProject.Domain.Customer
public void Update(Customer customer) { Customer old = GetById(customer.Id);
using (ISession session = NHibernateHelper.OpenSession()) using (ITransaction transaction = session.BeginTransaction()) { //session.Merge(old); //session.Lock(old, LockMode.None);
session.SaveOrUpdate(customer); transaction.Commit(); } } public Customer GetById(int customerId) { using (ISession session = NHibernateHelper.OpenSession()) return session.Get<Customer>(customerId); }
Thanks a lot for your help.
|