Cascade =“all”不保存子实体

时间:2011-07-22 17:18:39

标签: nhibernate nhibernate-mapping cascade

认为下面的对象模型是说Party和PartyName有多对一的关系。我认为cascade =所有我的Party.hbm应该让NHib保存孩子PartyName(s)。

但显然不是......

有人可以解释为什么PartyName没有与Party一起保存以及如何解决?

干杯,
Berryl

enter image description here

MAPPING

<class name="Party" table="Parties">
<id name="Id">
  <column name="PartyId" />
  <generator class="hilo" />
</id>

<discriminator column="Type" not-null="true" type="string" />

<set access="field.camelcase-underscore" cascade="all" inverse="true" name="Names">
  <key foreign-key="Party_PartyName_FK">
    <column name="PartyNameId" />
  </key>
  <one-to-many class="Parties.Domain.Names.PartyName, Parties.Domain" />
</set>

<subclass 
  name="Smack.Core.TestingSupport.NHibernate.TestableDomain.SomeDopeyDomainModel.Student, Smack.Core.TestingSupport" 
  discriminator-value="Student"
  >
  <property name="Number" />

  <many-to-one 
    class="Smack.Core.TestingSupport.NHibernate.TestableDomain.SomeDopeyDomainModel.Course, Smack.Core.TestingSupport" 
    foreign-key="Course_FK" 
    name="Course">
    <column name="CourseId" index="CourseIndex" />
  </many-to-one>
</subclass>

                            

<many-to-one access="field.camelcase-underscore" class="Parties.Domain.Party" foreign-key="Party_FK" name="Party">
  <column name="PartyId" index="PartyIndex" not-null="true"/>
</many-to-one>
<property name="TheRequiredName" not-null="true" length="50"/>
<property name="EverythingElse" />
<property name="ContextUsed" length="50"/>
<property name="Salutation" length="20"/>
<property name="EffectivePeriod" type="Smack.Core.Data.NHibernate.UserTypes.DateRangeUserType, Smack.Core.Data">
  <column name="EffectiveStart"/>
  <column name="EffectiveEnd"/>
</property>

失败测试(和输出)

    [Test]
    public void CanSaveAndLoad_AllProperties()
    {
        var partyName = NameSeeds.DevName;
        partyName.Party = _party;
        Assert.That(_party.Names.First(), Is.EqualTo(partyName));


        using (var tx = _session.BeginTransaction())
        {
            _session.Save(_party);
            tx.Commit();
        }
        _session.Clear();

        Party foundParty;
        using (var tx = _session.BeginTransaction())
        {
            foundParty = _session.Get<Party>(_party.Id); *** <=== name s/b saved!!
            tx.Commit();
        }
        PartyName foundName = foundParty.Names.First();
        //found.Look();

        Assert.That(foundName, Is.EqualTo(partyName));
        Assert.That(foundName.Party, Is.Not.Null);
        Assert.That(foundName.TheRequiredName, Is.EqualTo(partyName.TheRequiredName));
        Assert.That(foundName.EverythingElse, Is.EqualTo(partyName.EverythingElse));
        Assert.That(foundName.ContextUsed, Is.EqualTo(partyName.ContextUsed));
        Assert.That(foundName.Salutation, Is.EqualTo(partyName.Salutation));
        Assert.That(foundName.EffectivePeriod, Is.EqualTo(partyName.EffectivePeriod));
    }


NHibernate: INSERT INTO Parties (Type, PartyId) VALUES ('Parties.Domain.Party', @p0);@p0 = 32768 [Type: Int32 (0)]
NHibernate: SELECT party0_.PartyId as PartyId2_0_, party0_.Number as Number2_0_, party0_.CourseId as CourseId2_0_, party0_.Type as Type2_0_ FROM Parties party0_ WHERE party0_.PartyId=@p0;@p0 = 32768 [Type: Int32 (0)]

1 个答案:

答案 0 :(得分:2)

使用名称<set> inverse=true的映射,您必须在集合的每个成员上显式调用session.Save(partyNameObject)。如果您希望NHIBnate在保存PartyObject时自动保存集合的成员,则需要将名称<set>逆属性更改为inverse=false。这告诉Nhibernate你希望Party控制Party和PartyName之间的关系。您还必须记住将每个partyNameObject添加到Party.Names集合中。否则,当您致电Session.Save(partyObject)时,系统不会保存这些信息。请记住,让父控制关系可能很方便,但是如果你碰巧在没有加载PartyNames集合的情况下保存PartyObject,NHibernate会将他们的Party FK更新为Null。在此方案中,在名称<set>上设置了某些级联选项,您可能会发现Nhibernate也会删除它们。