nhibernate / fluenthibernate抛出StackOverflowException

时间:2010-05-19 17:00:33

标签: nhibernate fluent-nhibernate stack-overflow

在我的项目中,我使用的是NHibernate / FluentNHibernate,我正在使用两个实体,合同和服务。

这是我的合约类型:

[Serializable]
public partial class TTLCContract
{
    public virtual long? Id { get; set; }
    // other properties here
    public virtual Iesi.Collections.Generic.ISet<TTLCService> Services { get; set; }

    // implementation of Equals
    // and GetHashCode here
}

这是我的服务类型:

[Serializable]
public partial class TTLCService
{
    public virtual long? Id { get; set; }
    // other properties here
    public virtual Activity.Models.TTLCContract Contract { get; set; }

    // implementation of Equals
    // and GetHashCode here
}

好的,正如您所看到的,我希望我的合同对象拥有许多服务,并且每个服务都需要引用父合同。

我正在使用FluentNhibernate。所以我的映射文件如下:

public TTLCContractMapping()
{
    Table("tab_tlc_contracts");
    Id(x => x.Id, "tlc_contract_id");
    HasMany(x => x.Services)
            .Inverse()
            .Cascade.All()
            .KeyColumn("tlc_contract_id")
            .AsSet();
}

public TTLCServiceMapping()
{
     Table("tab_tlc_services");

     Id(x => x.Id, "tlc_service_id");
     References(x => x.Contract)
         .Not.Nullable()
         .Column("tlc_contract_id");
}

这就是我的问题:如果我检索数据库中所有合同的列表,它就可以了。如果我检索给定合同中的所有服务的列表,我得到一个StackOverflowException ....

你看到我写的东西有什么问题吗? 我犯了什么错误吗?

如果您需要任何其他信息,请与我们联系。

哦,是的,我错过了说...查看堆栈跟踪我看到系统正在加载所有服务,然后它再次加载与这些服务相关的合同。

我真的没有必要的经验和想法来了解正在发生的事情......所以任何帮助都会非常棒!

提前致谢, 干杯, 詹卢卡。

2 个答案:

答案 0 :(得分:1)

事实证明,两个类(TTLCContract&amp; TTLCService)都有一个自定义的GetHashCode()函数。

嗯,继续解释我感到惭愧......

TTLCContract的GetHashCode()正在调用自己字段的GetHashCode - 这是正确的。虽然,其中一个字段是“服务”,因此有一个调用,如Service.GetHashCode()。后一个函数是按照相同的原则构建的:它在每个内部字段上调用GetHashCode()函数。其中一个是合同。

因此,Contract.GetHashCode()调用Service.GetHashCode(),Service.GetHashCode()调用Contract.GetHashCode()。这个循环是StackOverflowException的原因。

实际上,情况比我刚才描述的情况要复杂得多:合同和服务确实有很多子对象,我在其中很多都有同样的问题。

我们的测试套件现在已被重写,以测试这些可能性。

答案 1 :(得分:0)

看起来好像你可能有一个循环引用发生。我的意思是你加载服务,这些服务会加载合同,然后加载服务然后再循环我们再去......

我不确定流利的nhibernate语法,但是请查看延迟加载服务和契约,这样就不会产生这种级联效果。