Scenario: Silverlight -> WCF -> NHibernate
- client requests a DTO from the server
- a corresponding DomainObject is retrieved via NHibernate
- a mapping layer translates the DomainObject to a DTO
- DTO is returned to the client
- client updates DTO and sends to server for update
- server maps DTO to new DomainObject
- Session.Merge(DomainObject) is called on empty ISession
This situation works perfectly when the following mapping file
doesn't contain the "Components" bag, including correct collection removals, updates, etc. However, when a second bag is added ie: "Components", all items in all collections are removed (see gen'd sql). What gives?
Mapping documents:
Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="test" namespace="test">
<class name="Recipe">
<id name="ObjectId">
<generator class="native">
<param name="sequence">recipeSeq</param>
</generator>
</id>
<version name="Version" type="Int64" generated="never" unsaved-value="0"/>
<property name="Name"/>
<bag name="PreparationSteps" table="preparationStep" inverse="true" cascade="all-delete-orphan">
<key column="recipeId"/>
<one-to-many class="PreparationStep"/>
</bag>
<bag name="Components" table="recipeComponent" inverse="true" cascade="all-delete-orphan">
<key column="recipeId"/>
<one-to-many class="RecipeComponent"/>
</bag>
</class>
</hibernate-mapping>
The generated SQL (show_sql=true):Code:
NHibernate: UPDATE Recipe SET Version = :p0, Name = :p1 WHERE ObjectId = :p2 AND Version = :p3; :p0 = '2', :p1 = 'Recipe 2139412171', :p2 = '892', :p3 = '1'
[color=red]NHibernate: DELETE FROM PreparationStep WHERE ObjectId = :p0 AND Version = :p1; :p0 = '1120', :p1 = '1'
NHibernate: DELETE FROM PreparationStep WHERE ObjectId = :p0 AND Version = :p1; :p0 = '1121', :p1 = '1'
NHibernate: DELETE FROM RecipeComponent WHERE ObjectId = :p0 AND Version = :p1; :p0 = '548', :p1 = '1'
NHibernate: DELETE FROM RecipeComponent WHERE ObjectId = :p0 AND Version = :p1; :p0 = '547', :p1 = '1'[/color]