我正在升级旧的NHibernate 1.2解决方案,我接管了NHib 3.1。我们在坚持父子关系方面遇到了问题。这给了我们这个错误:
NHibernate.StaleObjectStateException:行已被另一个事务更新或删除(或未保存的值映射不正确)
此代码在NHib 1.2中有效,但在3.1
中无效我们的保存方式与以下代码类似:
Film f = NewFilm();
Recipe r = new Recipe("2", TimeSpan.FromMinutes(15), TimeSpan.FromMinutes(15));
f.Recipe = r;
SaveAndFlush(f, r); //custom code that saves f then saves r then flushes through the session.
然而,如果我们保存r然后f并冲洗它可以工作。
我想知道为什么会发生这种情况,为什么NHib版本之间会发生变化。这是sesison认为实体现在是瞬态的方式吗?它是否以不同方式处理外键id生成器?
在旁注中,食谱的ID不等于电影的ID,我希望它可以做到。
HMB文件。 - 更新以包含完整文件
薄膜:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" schema="dbo">
<subclass name="Application.Core.Domain.Film, Application.Core" extends="Application.Core.Domain.VideoContent, Application.Core" discriminator-value="film" lazy="true">
<list inverse="false" lazy="true" name="Resources" access="field.camelcase-underscore" cascade="all-delete-orphan">
<key column="FilmId" />
<index column="PositionInFilm"/>
<one-to-many class="Application.Core.Domain.ContentResource, Application.Core" />
</list>
<list inverse="false" lazy="true" name="Steps" access="field.camelcase-underscore" cascade="all-delete-orphan">
<key column="FilmId" />
<index column="PositionInWebText"/>
<one-to-many class="Application.Core.Domain.WebText, Application.Core" />
</list>
<property name="FilmType" column="FilmType" />
<property name="PosterFrameTimeCode" column="PosterFrameTimeCode" />
<one-to-one name="Recipe" class="Application.Core.Domain.Recipe, Application.Core" cascade="save-update" access="field.camelcase-underscore"/>
<bag lazy="true" name="Shapes" access="field.camelcase-underscore" cascade="save-update" where="Archived=0">
<key column="ContentId"/>
<one-to-many class="Application.Core.Domain.FilmShape, Application.Core"/>
</bag>
<bag lazy="true" name="ArchivedShapes" access="field.camelcase-underscore" cascade="save-update" where="Archived=1">
<key column="ContentId"/>
<one-to-many class="Application.Core.Domain.FilmShape, Application.Core" />
</bag>
<many-to-one name="FilmToReplace" column="ReplacesFilmId" class="Application.Core.Domain.Film, Application.Core" access="field.camelcase-underscore" />
</subclass>
配方:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" schema="dbo">
<class name="Application.Core.Domain.Recipe,Application.Core" table="tbl_Recipe" lazy="false">
<id name="Id" column="HeaderId" type="System.Guid" access="field.camelcase-underscore">
<generator class="foreign">
<param name="property">Content</param>
</generator>
</id>
<list inverse="false" lazy="true" name="RecipeIngredients" access="field.camelcase-underscore" cascade="all-delete-orphan">
<key column="RecipeId" />
<index column="PositionInRecipe"/>
<one-to-many class="Application.Core.Domain.RecipeIngredient, Application.Core" />
</list>
<property name="Serves" column="Serves" type="System.String"/>
<property name="PreparationTime" column="PreparationTime" type="TimeSpan"/>
<property name="CookingTime" column="CookingTime" type="TimeSpan"/>
<property name="OvenTemperature" column="OvenTemperature" type="Application.Data.UserTypes.TemperatureType, Application.Data"/>
<one-to-one name="Content" class="Application.Core.Domain.Content, Application.Core" constrained="true" access="field.camelcase-underscore"/>
</class>
</hibernate-mapping>
答案 0 :(得分:0)
如果您对“子”实体进行级联保存,则只需保存父级。你不需要拯救孩子。
所以在这里你应该尝试只保存“f”。
答案 1 :(得分:0)
从文档中: http://nhibernate.info/doc/nh/en/index.html#mapping-declaration-onetoone
主键关联不需要 额外的表栏;如果两行是 相关的协会然后 两个表行共享相同的主表 核心价值。所以如果你想要两个对象 通过主键关联 协会,你必须确保 它们被分配了相同的标识符 值!
对于主键关联,请添加 以下映射到Employee和 人,分别。
<one-to-one name="Person" class="Person"/>
<one-to-one name="Employee" class="Employee" constrained="true"/>
现在我们必须确保主要的 PERSON和PERSON中相关行的键 员工表是平等的。我们使用了 特殊的NHibernate标识符 生成战略叫做外国:
<class name="Person" table="PERSON">
<id name="Id" column="PERSON_ID">
<generator class="foreign">
<param name="property">Employee</param>
</generator>
</id>
...
<one-to-one name="Employee"
class="Employee"
constrained="true"/>
</class>
新保存的Person实例是 然后分配相同的主键 作为Employee实例引用的值 与Employee属性 人