以下のコードとマッピングを考えると、なぜこのエラーが発生するのでしょうか?
失敗したテストからのエラー
[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 マッピング (親)
<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 マッピング (子)
<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" />