继续我在我的播客应用程序中对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)
答案 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,因为它认为该对象已经具有标识。