I have an aggregate root that creates another persistent entity and places it in a collection.
Typically, I try to avoid letting the internal id used within an aggregate boundary seep outside, but for the purpose of mapping the relevant instance to the ui data being sent, I needed to get the id and pass it back to the ui.
Using this mapping on the newly created entity:
<class name="AggregateRoot" table="RootsButNotTheBook">
<!--snip-->
<set name="ChildEntities" class="ChildEntity" cascade="all"> <!--more-->
</class>
<class name="ChildEntity" table="ChildEntities">
<id name="Id" type="Guid" >
<generator class="assigned"/>
</id>
<!--more mapping-->
and trying this code:
aggregateRoot.CreateChildEntityAndAddToCollection();
session.Update(aggregateRoot);
session.Flush();
Will get me this NHibernate exception:
NHibernate.StaleStateException: Unexpected row count: 0; expected: 1
Why? Well, inside my ChildEntity creation logic, I am generating an id for the entity so NHibernate thinks that it is a previously persisted entity ... but of course it isn't.
To make this work I change my child entity mapping to :
<class name="ChildEntity" table="ChildEntities">
<id name="Id" type="Guid" >
<generator class="assigned"/>
</id>
<version name="LastModifiedOn"
type="timestamp"
column="LastModifiedOn"
access="nosetter.camelcase" />
<!--more mapping-->
Adding the Versioning element to my entity now lets NHibernate know how to deal with the entity as it should and the code now works swimmingly.
The Hibernate documentation states:
A version or timestamp property should never be null for a detached instance, so Hibernate will detact any instance with a null version or timestamp as transient, no matter what other unsaved-value strategies are specified. Declaring a nullable version or timestamp property is an easy way to avoid any problems with transitive reattachment in Hibernate, especially useful for people using assigned identifiers or composite keys!
Therefore I actually used a nullable DateTime on my ChildEntity class, but things seemed to work even when I used a non-nullable DateTime, so I am not sure what I am missing there. Let me know if there are any errors in anything I present here...
Posted
07-29-2008 7:24 PM
by
Michael Nichols