开发者

Why is NHibernate doing an UPDATE rather than an INSERT?

Continuing my explorations in NHibernate with my podcast application, I've come across something odd开发者_开发技巧: NHibernate is UPDATEing when I would expect an INSERT. The situation is a simple one-to-many relationship between a podcast and its items. Here's my NHibernate mapping:

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

The situation is: I've created a new Podcast object, updated it from the feed (so the Podcast.FeedItems collection property contains a number of FeedItems) and am now saving it to the database via ISession.Save(). Judging by the NHibernate log file, the Podcast object is correctly inserted into the database, but the FeedItems collection is being UPDATEd instead. Here's the SQL generated for the 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
);

And here's the SQL generated for the FeedItems:

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

I don't get why an UPDATE is happening when the FeedItems don't necessarily even exist yet. I'm chasing this down, because the test that exercises this code is failing with the exception

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

Update with more logging: Following some more tweaks, I spotted the following line in the NHibernate log:

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


The key to this issue was the exception message

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

Thanks to this question I realised that my IDs were being assigned by my own code and not by NHibernate, which caused NHibernate to think that the entities had already been saved. Once I removed the code auto-generating new IDs, the problem went away.


I've seen this happen when the unsaved-value attribute on my element didn't match up against the corresponding property value for a new entity. Here's an example:

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

and

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

In this case, saving a new Foo will result in NHib generating an UPDATE since it thinks that the object already has an identity.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜