2010-05-19 4 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"); 
} 

여기 내 문제 온다 : 나는 DB에서 모든 계약의 목록을 검색하는 경우, 그것은 작동 그래서 내 매핑 파일은 다음과 같습니다. 주어진 계약에서 모든 서비스 목록을 검색하면 StackOverflowException이 발생합니다 ....

내가 작성한 내용에 이상이 있습니까? 실수를 저질렀습니까?

추가 정보가 필요하면 알려주십시오.

아, 예기치 않게 ... 시스템이 모든 서비스를로드하고있는 스택 트레이스를보고 그 서비스와 관련된 계약을 다시로드하고 있습니다.

나는 무슨 일이 일어나고 있는지 이해하기 위해 더 이상 필요한 경험이나 아이디어가 없다. 그래서 도움이 정말 정말 좋을 것입니다!

미리 감사드립니다. 건배, Gianluca.

+0

정말 거기에 반비례가 필요합니까? –

+0

글쎄,이 문제를 해결하기 위해 내가 쓴 것입니다. 내가 말했듯이, 나는 아이디어가 부족했다 :/오, 또한 .. 나는 그것 없이는 다른 예외를 얻고 있었다. 그래서 나는 그것이 필요하다고 생각한다. 테이블 tab_services에는 계약에 대한 참조가있다 (그러므로, tab_tlc_services. tlc_contract_id), 그래서 나는 바로 거기에 있을지도 모른다고 생각한다. 그러나 앞에서 말했듯이 나는 전문가들의 제안을 받아 들인다 ... –

+0

전체 예외 ('ex.ToString()')를 게시 할 수 있습니까? –

답변

1

두 클래스 (TTLCContract & TTLCService)에는 사용자 지정된 GetHashCode() 함수가 있습니다.

글쎄, 나는

TTLCContract의 GetHashCode

()가 자신의 필드의 GetHashCode는 호출 된 ... 설명과에서 수행하는 거의 부끄러워 - 그리고 맞아. 하지만이 필드 중 하나가 "Service"였으므로 Service.GetHashCode()와 같은 호출이있었습니다. 이 후자의 함수는 동일한 원칙에 따라 작성되었습니다. 내부 필드 각각에 대해 GetHashCode() 함수를 호출했습니다. 그리고 그 중 하나가 계약입니다.

따라서 Contract.GetHashCode()가 Service.GetHashCode()를 호출하고 Service.GetHashCode()가 Contract.GetHashCode()를 호출하는 중입니다. 이 루프는 StackOverflowException의 원인입니다.

실제로 상황은 방금 설명한 것보다 훨씬 복잡했습니다. 계약 및 서비스에는 실제로 많은 자식 개체가 있고 많은 문제에서 동일한 문제가있었습니다.

이제 테스트 스위트가 다시 작성되어 이러한 우발적 인 상황을 테스트합니다.

0

순환 참조가 발생할 수있는 것처럼 보입니다. 그건 내 말은 당신이 서비스를로드 한 다음에 서비스를로드하고 다시 시작하는 서비스를로드하는 서비스를로드한다는 것입니다 ...

유창한 nhibernate 구문은 확실하지 않지만 서비스와 계약 모두를 느슨하게로드해야합니다. 그래서 당신은이 계단식 효과를 얻지 못합니다.

+0

NHibernate 레퍼런스와 콜렉션은 기본적으로 게으르며, 그렇지 않은 경우에도 신원 맵은 순환 참조가 작동 함을 보장한다. –

+1

설명을위한 Diego 감사합니다. 항상 그랬던가 아니면 최근에 디폴트로 게으르도록 변경 되었습니까? –

관련 문제