2010-05-19 34 views
3

在我的项目中,我使用NHibernate/FluentNHibernate,并且我正在使用两个实体,合同和服务。nhibernate/fluenthibernate抛出StackOverflowException

这是我的合同类型:

[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 ...。

您是否看到我写的内容有错? 我犯了什么错误吗?

如果您需要任何其他信息,请让我知道。

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

我真的没有必要的经验,也没有想法了解发生了什么事情..所以任何帮助将真的很棒!

在此先感谢, 干杯, Gianluca。

+0

你真的需要那里的逆向吗? – 2010-05-19 17:07:53

+0

那么,这是我为了尝试排除这个问题而提出的。正如我所说,我用完了想法:/哦,也..我没有它得到一个不同的异常,所以我想它是需要的...在表tab_services有一个对合同的引用(因此,tab_tlc_services。 tlc_contract_id),所以我想我可能会在那里..但正如我前面所说,我接受专家的建议... – 2010-05-19 17:18:21

+0

你能发布完整的异常('ex.ToString()')吗? – 2010-05-20 00:44:28

回答

1

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

嗯,我觉得几乎羞于解释进行...

TTLCContract的GetHashCode()方法被调用自身的字段的GetHashCode的 - 这是正确的。尽管这些字段之一是“Service”,因此有一个诸如Service.GetHashCode()的调用。后一个函数是按照相同的原理构建的:它在每个内部字段上调用GetHashCode()函数。其中之一是合同。

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

事实上,情况比我刚刚描述的情况要复杂得多:合同和服务确实有许多子对象,而且我在其中许多对象上也遇到同样的问题。

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

0

看起来好像您可能会发生循环参考。我的意思是你加载的服务,它载入合同,然后加载服务,然后我们再次回合...

我不确定流利的nhibernate语法,但期待延迟加载服务和合同所以你不会得到这个级联效应。

+0

默认情况下,NHibernate引用和集合是懒惰的,即使它们不是,标识映射也可以保证循环引用的正常工作。 – 2010-05-20 00:43:33

+1

感谢迭戈澄清。它一直是这种情况,或者最近只是默认情况下被改为懒惰? – 2010-05-20 01:04:39

相关问题