升级到Hibernate 3后,一对一关系中的孩子的持久性失败

时间:2011-05-12 08:53:35

标签: nhibernate nhibernate-mapping

我正在升级旧的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>

2 个答案:

答案 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属性   人