Почему NHibernate делает ОБНОВЛЕНИЕ, а не ВСТАВКА? - PullRequest
0 голосов
/ 12 ноября 2009

Продолжая исследования в NHibernate с моим приложением для подкастов, я натолкнулся на нечто странное: NHibernate ОБНОВЛЯЕТСЯ, когда я ожидаю ВСТАВКУ. Ситуация представляет собой простое отношение «один ко многим» между подкастом и его элементами. Вот мое отображение NHibernate:

<hibernate-mapping assembly="App.DataModel">
  <class name="Feed" table="Feeds">
    <!-- snip -->
    <bag name="FeedItems" table="FeedItems" cascade="all">
      <key column="FeedId" />
      <one-to-many class="FeedItem" />
    </bag>
  </class>
</hibernate-mapping>

Ситуация такова: я создал новый объект Podcast, обновил его из ленты (поэтому свойство коллекции FeedItems Podcast содержит число FeedItem с) и теперь сохраняю его в базе данных через ISession.Save(). Судя по файлу журнала NHibernate, объект Podcast правильно вставлен в базу данных, но вместо этого коллекция FeedItems обновляется. Вот SQL, сгенерированный для Podcast:

INSERT INTO Feeds (
    Uri, IsPublic, Title, Description, Link, Language, Copyright, 
    LastBuildDate, PublishDate, Docs, Webmaster, Author, Subtitle, 
    Summary, OwnerName, OwnerEmail, IsExplicit, ImageUri, Id 
) VALUES (
    @p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10, @p11, 
    @p12, @p13, @p14, @p15, @p16, @p17, @p18
);

А вот SQL, сгенерированный для FeedItem s:

UPDATE FeedItems SET PublishDate = @p0, Author = @p1, 
    IsExplicit = @p2, Subtitle = @p3, Summary = @p4, 
    Duration = @p5 WHERE Id = @p6;

Я не понимаю, почему ОБНОВЛЕНИЕ происходит, когда FeedItem не обязательно даже существует. Я преследую это, потому что тест, который выполняет этот код, терпит неудачу за исключением

NHibernate.StaleStateException: Unexpected row count: 0; expected: 1

Обновление с дополнительным ведением журнала : После еще нескольких настроек я обнаружил следующую строку в журнале NHibernate:

Collection found: [Podcast.FeedItems#GUID], was: [<unreferenced>] (initialized)

Ответы [ 2 ]

6 голосов
/ 12 ноября 2009

Ключом к этой проблеме было сообщение об исключении

NHibernate.StaleStateException: Unexpected row count: 0; expected: 1

Благодаря этому вопросу Я понял, что мои идентификаторы назначаются моим собственным кодом, а не NHibernate, что заставило NHibernate думать, что объекты уже были сохранены. Как только я удалил код, автоматически генерирующий новые идентификаторы, проблема ушла.

2 голосов
/ 12 ноября 2009

Я видел, как это происходило, когда атрибут unsaved-value в моем элементе не совпадал с соответствующим значением свойства для новой сущности. Вот пример:

<class name="Foo">
  <id name="ID" unsaved-value="-1" type="Int32">
    <generator class="native"/>
  </id>
</class>

и

public class Foo 
{
  private int _id = 0;
  public int ID {
    get { return _id; }
    set { _id = value; }
  }
}

В этом случае сохранение нового Foo приведет к тому, что NHib сгенерирует UPDATE, поскольку он считает, что объект уже имеет идентичность.

...