NHibernate为什么要进行UPDATE而不是INSERT?

时间:2009-11-11 23:31:30

标签: nhibernate nhibernate-mapping

继续我在我的播客应用程序中对NHibernate的探索,我遇到了一些奇怪的事情:当我期望INSERT时,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对象,从Feed更新了它(因此Podcast。FeedItems集合属性包含许多FeedItem s)和am现在通过ISession.Save()将其保存到数据库。根据NHibernate日志文件判断,Podcast对象已正确插入数据库,但FeedItems集合正在UPDATEd中。这是为Podcast生成的SQL:

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

这是为FeedItem生成的SQL:

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

FeedItem s尚未存在时,我不明白为什么会发生UPDATE。我正在追逐这个,因为执行此代码的测试失败并出现异常

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

使用更多日志记录进行更新:经过一些更多调整后,我在NHibernate日志中发现了以下行:

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

2 个答案:

答案 0 :(得分:6)

此问题的关键是异常消息

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

感谢this question我意识到我的ID是由我自己的代码而不是NHibernate分配的,这导致NHibernate认为实体已经被保存了。一旦我删除了代码自动生成新ID,问题就消失了。

答案 1 :(得分:2)

我已经看到当元素上的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,因为它认为该对象已经具有标识。