Ошибка сохранения многоуровневой иерархии Nhibernate? - PullRequest
0 голосов
/ 29 июля 2009

У меня есть база данных с 6-уровневой иерархией и модель предметной области. как то так:

Категория -Подкатегория -Контейнер -DataDescription | Метаданные -Data

Используемое мэппинг выглядит следующим образом:

  <class name="Category, Sample" table="Categories">
    <id name="Id" column="Id" type="System.Int32" unsaved-value="0">
      <generator class="native"/>
    </id>    
    <property name="Name" access="property" type="String" column="Name"/>
    <property name="Metadata" access="property" type="String" column="Metadata"/>
    <bag name="SubCategories" 
         cascade="save-update" 
         lazy="true" 
         inverse="true">
      <key column="Id" foreign-key="category_subCategory_fk"/>
      <one-to-many class="SubCategory, Sample" />
    </bag>
  </class>

<class name="SubCategory, Sample" table="SubCategories">
    <id name="Id" column="Id" type="System.Int32" unsaved-value="0">
        <generator class="native"/>
    </id>
    <many-to-one name="Category"
                 class="Category, Sample"
                 foreign-key="subCat_category_fk"/>

    <property name="Name" access="property" type="String"/>
    <property name="Metadata" access="property" type="String"/>

    <bag name="Containers"
         inverse="true"
         cascade="save-update"
         lazy="true">
        <key column="Id" foreign-key="subCat_container_fk" />
        <one-to-many class="Container, Sample" />
    </bag>
</class>

<class name="Container, Sample" table="Containers">
    <id name="Id" column="Id" type="System.Int32" unsaved-value="0">
        <generator class="assigned"/>
    </id>
    <many-to-one name="SubCategory"
                 class="SubCategory,Sample"                  
                 foreign-key="container_subCat_fk"/>    

    <property name="Name" access="property" type="String" column="Name"/>

    <bag name="DataDescription" cascade="all" lazy="true" inverse="true">
        <key column="Id" foreign-key="container_ DataDescription_fk"/>
        <one-to-many class="DataDescription, Sample" />
    </bag>

    <bag name="MetaData" cascade="all" lazy="true" inverse="true">
        <key column="Id" foreign-key="container_metadata_cat_fk"/>
        <one-to-many class="MetaData, Sample" />
    </bag>
</class>

По какой-то причине, когда я пытаюсь сохранить категорию (с вложенной подкатегорией, контейнером и т. Д.), Я получаю нарушение внешнего ключа из базы данных.

Код выглядит примерно так (псевдо).

var category = new Category();
var subCategory = new SubCategory();
var container = new Container();
var dataDescription = new DataDescription();
var metaData = new MetaData();

category.AddSubCategory(subCategory);
subCategory.AddContainer(container);
container.AddDataDescription(dataDescription);
container.AddMetaData(metaData);

Session.Save(category);

Вот лог из этого теста:

DEBUG NHibernate.SQL - INSERT INTO Categories (Name, Metadata) VALUES (@p0, @p1); select SCOPE_IDENTITY(); @p0 = 'Unit test', @p1 = 'unit test'

DEBUG NHibernate.SQL - INSERT INTO SubCategories (Category, Name, Metadata) VALUES (@p0, @p1, @p2); select SCOPE_IDENTITY(); @p0 = '1', @p1 = 'Unit test', @p2 = 'unit test'

DEBUG NHibernate.SQL - INSERT INTO Containers (SubCategory, Name, Frequency, Scale, Measurement, Currency, Metadata, Id) VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7); @p0 = '1', @p1 = 'Unit test', @p2 = '15', @p3 = '1', @p4 = '1', @p5 = '1', @p6 = 'unit test', @p7 = '0'

ERROR NHibernate.Util.ADOExceptionReporter - The INSERT statement conflicted with the FOREIGN KEY constraint "subCat_container_fk". The conflict occurred in database "Sample", table "dbo.SubCategories", column 'Id'.

Способы добавления элементов к объектам всегда следующие:

public void AddSubCategory(ISubCategory subCategory)
{
    subCategory.Category = this;
    SubCategories.Add(subCategory);
}

Что мне не хватает ??

Спасибо, nisbus

1 Ответ

0 голосов
/ 30 июля 2009

Ну, я нашел ошибку.

Мне нужно было назвать столбцы в сопоставлениях «один-ко-многим» и «многие-к-одному» чем-то, кроме Id, чтобы эта работа работала правильно.

Правильное отображение будет выглядеть примерно так:

 <class name="Category, Sample" table="Categories">
    <id name="Id" column="Id" type="System.Int32" unsaved-value="0">
      <generator class="native"/>
    </id>    
    <property name="Name" access="property" type="String" column="Name"/>
    <property name="Metadata" access="property" type="String" column="Metadata"/>
    <bag name="SubCategories" 
         cascade="save-update" 
         lazy="true" 
         inverse="true">
      <key column="Category_Id" foreign-key="category_subCategory_fk"/>
      <one-to-many class="SubCategory, Sample" />
    </bag>
  </class>

<class name="SubCategory, Sample" table="SubCategories">
        <id name="Id" column="Id" type="System.Int32" unsaved-value="0">
                <generator class="native"/>
        </id>
        <many-to-one name="Category"
                                 class="Category, Sample"
                                 column="Category_Id"
                                 foreign-key="subCat_category_fk"/>

        <property name="Name" access="property" type="String"/>
        <property name="Metadata" access="property" type="String"/>

        <bag name="Containers"
                 inverse="true"
                 cascade="save-update"
                 lazy="true">
                <key column="Container_Id" foreign-key="subCat_container_fk" />
                <one-to-many class="Container, Sample" />
        </bag>
</class>

Теперь все отлично работает.

Спасибо, nisbus

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...