nhibernate mapping не сохраняет / вставляет ключи вставленных подклассов

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

После этого возникла еще одна проблема - проблема с вставкой ключей в базу данных. Ситуация выглядит следующим образом:

У меня есть объект с 2 уровнями подклассов, оба коллекции.

Давайте назовем объект Parent, у этого есть коллекция потомков, и у каждого подразделения в этом собрании есть своя коллекция объектов. Которые отображаются следующим образом.

Родительское отображение его <set>

<!--Parent-->
<set name="Collection"
     table="Table"
     cascade="all-delete-orphan"
     batch-size="15"
     inverse="true">
  <key column="ParentID"/>
  <one-to-many class="CollectionObject,CollectionObject-ns"/>
</set

CollectionObject's Mapping

<id name="ID" column="ID">
  <generator class="native"/>
</id>

<!-- property mappings-->
<property name="ParentID" column="ParentID" not-null="true"/>

<!--collection mapping-->
<set name="Collection"
     table="Table"
     cascade="all-delete-orphan"
     inverse="true"
     batch-size="15">
  <key column="ChildID"/>
  <one-to-many class="CollectionObject,CollectionObject-ns"/>
</set>

Отображение отображения объекта во 2-й коллекции аналогично приведенному выше. Предполагаемый сценарий будет, я сохраняю Родителя, это вызовет сохранение подклассов / коллекций.

Например, у меня есть Родитель с ID = 1, Родитель заполнен 1 коллекцией, и у этой коллекции есть 1 собственная коллекция.

Поэтому я сохраняю Parent, родитель получает идентификатор из базы данных (собственный идентификатор sql). Теперь первая коллекция должна получить свойство ParentID, заполненное идентификатором, который родительский объект только что получил из базы данных. И коллекция должна получить ChildID, заполненный идентификатором, который Ребенок получил из базы данных так же, как Родитель получил свой идентификатор.

Теперь происходит следующее (я проверил созданный SQL в NHProf). Все вставляется с собственным идентификатором, но коллекции не получают заполненную ключевую колонку с идентификатором родительского класса. (вместо этого просто вставляется 0)

Таким образом, мой вопрос сводится к тому, что я забыл добавить к своему отображению, что и должно произойти? Ключевой столбец не делает то, что я думаю, что он должен делать?

Если я забуду что-нибудь добавить, пожалуйста, так и скажите. Я с удовольствием предоставлю дополнительную информацию.

Обновить

Я думаю, что проблема может быть связана с детьми, не имеющими <many-to-one> тег. Поэтому я попытался добавить один из них к первому дочернему сопоставлению. Я придумал это

   <many-to-one name="ParentID"
             class="Parent,Parent-ns"
             column="ParentID"
             not-null="true"/>

Тем не менее, эта настройка дает мне следующую ошибку.Exception occurred getter of Parent.ParentID

с InnerException{"Object does not match target type."}

К сожалению, эта ошибка не дает мне никаких идей о том, где продолжить.

2 ответа

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

<property name="ParentID" column="ParentID" not-null="true"/> 

из вашего картографирования и заменили его множеством к одному? Наконец, если вы хотите, чтобы ваши дочерние объекты имели коллекции дочерних объектов, тогда дочернему объекту также понадобится много-к-одному

<many-to-one name="CollectionObjectParent"
             class="CollectionObject,CollectionObject-ns"
             column="ChildID"
             not-null="true"/>

К сожалению, после игры с отображениями и чтения через половину Интернета я не смог решить эту проблему.

Проблема заключается в том, что я не могу добраться до сценария, который <Document> получает свой ключ из базы данных <generator class="native"/> и после этого вставляет этот ключ в свойства foreignkey его базовых классов, внутри всего одного session.Save() вызов.

например, для сценария я хотел бы session.Save(document)

- * обнаружен новый документ - * получить новую личность

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

и повторите это со всеми основными классами.

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

Я еще не разочаровался в правильном решении этого вопроса, но на данный момент это нужно сделать. Все еще открывай для лучшего движения.

входящий код дерьма!

    public void InsertDocument(Document document)
    {
        using (ISession session = NHibernateHelper.OpenSession())
        {
            using (ITransaction transaction = session.BeginTransaction())
            {
                 try
                 {                                          
                    IDocument document2 = new Document();
                    document2.Bodyregels = document.Bodyregels;
                    //for making the query a little neater
                    document.Bodyregels = null;                        

                    //lets get the elusive identity
                    session.Save(document);
                    session.Flush();

                    //reattach subclass and enter the id explicitly
                    document.Bodyregels = document2.Bodyregels;
                    foreach (DocumentBodyregel dbr in document.Bodyregels)
                    {
                        dbr.DocumentID = document.DocumentID;
                    }

                    //save it again, now with filled FK
                    session.Save(document);
                    session.Flush();

                    //now save the final subclass with FK's
                    foreach (DocumentBodyregel dbr in document.Bodyregels)
                    {
                        foreach (DocumentBodyregelWaarde dbrw in dbr.Waardes)
                        {
                            dbrw.RegelID = dbr.ID;
                            dbrw.DocumentID = document.DocumentID;
                        }
                    }

                    //and save the entire thing again (now with FK's)
                    session.Save(document);
                    transaction.Commit();
                }
                catch (Exception e)
                {
                    transaction.Rollback();
                    throw e;
                }
            }
        }
    }
Другие вопросы по тегам