【问题标题】:Using AuditInterceptor - object references an unsaved transient instance - save the transient instance before flushing使用 AuditInterceptor - 对象引用未保存的瞬态实例 - 在刷新之前保存瞬态实例
【发布时间】:2010-12-12 16:07:05
【问题描述】:

使用 AuditInterceptor 填充 DomainObject 的 审计字段 的域模型。

DomainObject
   Id
   EstablishDate
   EstablishId
   UpdateDate
   UpdateId

Message : DomainObject
   Description
   MessageDistributions

Distribution : DomainObject
   BeginEffective
   EndEffective
   MessageDistributions

MessageDistribution : DomainObject
   Distribution
   Message

在这种 ManyToMany 关系中,MessageDistribution 还实现了 DomainObject 以使用 AuditInterceptor。这使我无法在 FluentNHibernate 映射中使用 HasManyToMany 子句。

这是映射代码。

public class MessageMap : ClassMap<Message>
{
  public MessageMap()
    {
        WithTable("Message");

        Id(x => x.Id).GeneratedBy.Identity().ColumnName("MessageSeq").WithUnsavedValue(0);
        Map( x => x.Description ).ColumnName( "SummaryName" );
        Map(x => x.EstablishDate);
        Map(x => x.EstablishId);
        Map(x => x.UpdateDate);
        Map(x => x.UpdateId);


        HasMany( x => x.MessageDistributions )
            .KeyColumnNames.Add( "MessageSeq" )
            .Access.AsCamelCaseField( Prefix.Underscore )
            .Cascade.All().Inverse();

    }
}

public class MessageDistributionMap : ClassMap<MessageDistribution>
{
    public MessageDistributionMap()
    {
        WithTable("MessageDistribution");

        Id(x => x.Id).GeneratedBy.Identity().ColumnName("MessageDistributionSeq").WithUnsavedValue(0);

        Map(x => x.EstablishDate);
        Map(x => x.EstablishId);
        Map(x => x.UpdateDate);
        Map(x => x.UpdateId);

        References(x => x.Message).ColumnName("MessageSeq");
        References(x => x.Distribution).ColumnName("DistributionSeq");
    }
}

public class DistributionMap : ClassMap<Distribution>
{
    public DistributionMap()
    {
        WithTable("Distribution");

        Id(x => x.Id).GeneratedBy.Identity().ColumnName("DistributionSeq").WithUnsavedValue(0);

        Map(x => x.BeginEffectiveDate);
        Map(x => x.EndEffectiveDate);
        Map(x => x.EstablishDate);
        Map(x => x.EstablishId);
        Map(x => x.UpdateDate);
        Map(x => x.UpdateId);

        HasMany( x => x.MessageDistributions )
            .KeyColumnNames.Add( "DistributionSeq" )
            .Access
            .AsCamelCaseField( Prefix.Underscore )
            .Cascade.All().Inverse();
    }
}

下面是实现上述关系的测试。

[Test]
public void Should_Add_A_Message_To_Existing_Distribution()
{
    var desc = "Test message " + DateTime.Now;
    var message = new Message { Description = desc, PumpType = 1 };

    var distribution = new Distribution
                           {
                               BeginEffectiveDate = new DateTime( 2009, 9, 2 ),
                               EndEffectiveDate = new DateTime( 2009, 9, 10 ),
                               Priority = 1
                           };
    var messageDistribution = new MessageDistribution { Distribution = distribution };

    message.AddMessageDistribution(messageDistribution);

    _repository.Save( message );
    _repository.Clear();

    var retrievedMessage = _repository.GetById(message.Id);

    Assert.AreEqual(message, retrievedMessage);

    Assert.AreEqual(distribution, retrievedMessage.MessageDistributions[0].Distribution);
}

我使用测试运行程序执行测试,并导致 _repository.Save(message); 行出现以下错误

    NHibernate.TransientObjectException: 
    object references an unsaved transient instance - 
save the transient instance before flushing: 
    Speedway.StoreOperations.CrindMessaging.Core.Domain.Distribution

在我的 AuditInterceptor 中,我有一个

Debug.WriteLine(string.Format("{0} : {1}", propertyNames[i], state[i]));

在“OnSave 和 OnFlushDirty”事件中。

我可以看到 Message 和 MessageDistribution 正在通过,但 Distribution 实体从未被触及。

所以我的问题是,我的 FluentMapping 有什么问题吗?我在错误的地方有“逆”吗?有没有人遇到过这种情况?

【问题讨论】:

    标签: nhibernate many-to-many instance transient


    【解决方案1】:

    您的 FluentMapping 看起来不错。 尝试在测试中更改以下行:

    var messageDistribution = new MessageDistribution { Distribution = distribution };
    

    用这个:

    var messageDistribution = new MessageDistribution { Distribution = distribution, Message = message };
    

    然后再试一次。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-11-08
      • 2015-09-27
      • 2021-03-03
      • 2013-11-30
      • 2017-04-12
      • 1970-01-01
      相关资源
      最近更新 更多