2011-05-12 43 views
1

我正在升級一箇舊的NHibernate 1.2解決方案,我接管了NHib 3.1。我們在堅持親子關係方面遇到問題。這給了我們這樣的錯誤:堅持一對一關係上的孩子在更新到NHibernate後失敗3

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. 

但是,如果我們保存,則成爲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

'在一個側面說明,配方的ID不等於膜的ID,其我希望它能做到.'對於ID平等,你應該使用generator class =「foreign」 – jjjjj 2011-05-12 09:08:06

+0

這似乎沒有影響1.2版本。他們堅持與正確的協會。 – 2011-05-12 09:09:22

+0

你可以添加電影和食譜的完整映射嗎? – jjjjj 2011-05-12 09:14:20

回答

0

如果你有一個級聯保存在一個 「孩子」 的實體,您只需保存父。你不需要保存孩子。

所以在這裏你應該嘗試只保存「f」。

+0

這也不起作用。所以可能會有更深層次的問題? – 2011-05-12 10:12:31

0

從文檔: http://nhibernate.info/doc/nh/en/index.html#mapping-declaration-onetoone

Primary key associations don't need an extra table column; if two rows are related by the association then the two table rows share the same primary key value. So if you want two objects to be related by a primary key association, you must make sure that they are assigned the same identifier value!

For a primary key association, add the following mappings to Employee and Person, respectively.

<one-to-one name="Person" class="Person"/> 

<one-to-one name="Employee" class="Employee" constrained="true"/> 

Now we must ensure that the primary keys of related rows in the PERSON and EMPLOYEE tables are equal. We use a special NHibernate identifier generation strategy called foreign:

<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> 

A newly saved instance of Person is then assigned the same primar key value as the Employee instance refered with the Employee property of that Person.