不理解这个错误

时间:2012-10-25 11:54:08

标签: nhibernate nhibernate-mapping

鉴于下面的代码和映射,我为什么会收到此错误?

测试失败错误

    [Test]
    public void Cascade_Can_Persist_Hero_Without_Epic()
    {
        _epic = new Epic("illiad");
        var hero = new GreekHero("ted");
        hero.SetEpic(_epic);
        _session.SaveOrUpdate(_epic);
        _session.Flush();
        _session.Evict(_epic);
        Assert.That(_epic.IsPersistent());
        Assert.That(hero.IsPersistent());

        var found = _session.Get<GreekHero>(hero.Id);
        found.Look();

        Assert.That(found, Is.EqualTo(hero));
    }

NHibernate: select next_hi from hibernate_unique_key
NHibernate: update hibernate_unique_key set next_hi = @p0 where next_hi = @p1;@p0 = 6 [Type: Int32 (0)], @p1 = 5 [Type: Int32 (0)]
NHibernate: select next_hi from hibernate_unique_key
NHibernate: update hibernate_unique_key set next_hi = @p0 where next_hi = @p1;@p0 = 7 [Type: Int32 (0)], @p1 = 6 [Type: Int32 (0)]
NHibernate: 
    INSERT INTO Epic (EpicName, EpicId) 
    VALUES (@p0, @p1);
        @p0 = 'illiad' [Type: String (0)], 
        @p1 = 163840 [Type: Int32 (0)]
NHibernate: 
    INSERT INTO GreekHero (HeroName, EpicId, GreekHeroId) 
    VALUES (@p0, @p1, @p2);
        @p0 = 'ted' [Type: String (0)], 
        @p1 = 163840 [Type: Int32 (0)], 
        @p2 = 196608 [Type: Int32 (0)]
Test 'Core.Data.Tests.NHibernate.Bootstraps.MappingTests.CollectionMappingConstraintTests.Cascade_Can_Persist_Hero_Without_Epic' failed:
    NHibernate.Exceptions.GenericADOException : could not insert: 
    [Core.TestingSupport.GreekGods.Domain.GreekHero#196608][SQL: INSERT INTO GreekHero (HeroName, EpicId, GreekHeroId) VALUES (?, ?, ?)]
  ----> System.Data.SqlServerCe.SqlCeException : 
  A foreign key value cannot be inserted because a corresponding primary key value does not exist. [ Foreign key constraint name = FK253126F517FE25F6 ]

对象模型(父级)

public class Epic : Entity
{
    ...

    [UsedImplicitly] // NHib uses this
    public Epic() {
        _greekHeroes = new HashedSet<GreekHero>();
    }

    /// <summary>
    /// The backing store for order items. NHib will set this when loaded from the db.
    /// </summary>
    private readonly Iesi.Collections.Generic.ISet<GreekHero> _greekHeroes;

    /// <summary>
    /// An enumeration of greek heros for public consumption.
    /// </summary>
    public virtual IEnumerable<GreekHero> GreekHeroes { get { return _greekHeroes; } }

    public virtual bool AddItem(GreekHero newItem)
    {
        if (!ReferenceEquals(newItem, null) && _greekHeroes.Add(newItem))
        {
            newItem.SetEpic(this);
            return true;
        }
        return false;
    }

    public virtual bool RemoveItem(GreekHero itemToRemove)
    {
        if (!ReferenceEquals(itemToRemove, null) && _greekHeroes.Remove(itemToRemove))
        {
            itemToRemove.SetEpic(null);
            return true;
        }
        return false;
    }
}

对象模型(子)

public class GreekHero : Entity
{
    ...

    #endregion

    #region Epic (a Greek Hero may be associated with an Epic)

    /// <summary>
    /// The Epic associated with this Greek Hero.
    /// </summary>
    public virtual Epic Epic { get; protected set; }

    /// <summary>
    /// This enforces referential integrity in the object model between this <see cref="GreekHero"/>
    /// and the <see cref="Domain.Epic.GreekHeroes"/>.
    /// </summary>
    /// <param name="epic">The new epic associated with this hero.</param>
    /// <remarks><seealso cref="Domain.Epic.AddItem"/> and <seealso cref="Domain.Epic.RemoveItem"/></remarks>
    public virtual void SetEpic(Epic epic)
    {
        var prevEpic = Epic;
        if (epic == prevEpic) return;

        Epic = epic;

        if (!ReferenceEquals(prevEpic, null))
            prevEpic.RemoveItem(this);

        if (!ReferenceEquals(epic, null))
            epic.AddItem(this);
    }

    #endregion
}

HBM Mapping(父级)

<id name="Id">
  <column name="EpicId" />
  <generator class="hilo" />
</id>

<natural-id>
  <property name="EpicName" length="30" />
</natural-id>

<set name="GreekHeroes"
     cascade="all-delete-orphan"
     inverse="true"
     access="field.camelcase-underscore">
  <key column="GreekHeroId" />
  <one-to-many class="GreekHero"/>
</set>

HBM Mapping(子)

<id name="Id">
  <column name="GreekHeroId" />
  <generator class="hilo" />
</id>

<natural-id>
  <property name="HeroName" length="30" />
</natural-id>

<many-to-one name="Epic" column="EpicId" />

1 个答案:

答案 0 :(得分:1)

&lt; key&gt; &lt; set&gt;中的元素表示子表中要存储 parent 的键的列。在你的情况下,它应该是“EpicId”,因为这是你在&lt; many-to-one&gt;中声明的内容。