Reputation: 12833
Given the code and mapping below, Why am I getting this error?
[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
}
<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>
<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" />
Upvotes: 0
Views: 171
Reputation: 5629
The <key> element in <set> indicates the column in the child table where the key of the parent is to be stored. In your case it should be "EpicId" since that is what you state in the <many-to-one>.
Upvotes: 1