2010-05-19 75 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

相關問題