2010-07-28 3 views
1

나는 아래에 나와있는 MVC/Nhibernate 응용 프로그램을 가지고 있습니다.오류 :로드하는 객체가 잘못된 클래스 임

[WrongClassException: Object with id: f7eab616-76b2-4602-8643-b4466e91a33f was not of the specified subclass: AgileThought.ERP.Domain.CRM.Client (loading object was of wrong class [AgileThought.ERP.Domain.HR.SalesRepresentative])] NHibernate.Loader.Loader.InstanceAlreadyLoaded(IDataReader rs, Int32 i, IEntityPersister persister, EntityKey key, Object obj, LockMode lockMode, ISessionImplementor session) +229

나는 줄 NHibernate.Loader.Loader.InstanceAlreadyLoaded 개체가 이미로드 말한다 스택 추적에서 생각합니다.

문제는 개체가 동일한 GUID를 가진 몇 가지 유형이 될 수 있다는 것입니다. IE

클라이언트 내 사용자 계정은 세 가지 엔티티 유형이 한 사람

직원이 내 dev 환경에서

직원

에서 사람

영업 담당자 상속에서 상속에서 상속됩니다.

문제는 이제 클라이언트에서 검색 할 때 영업 담당자의 GUID를보고 영업 담당자 개체가 필요하다고 가정합니다. 내 코드의 다음 줄이 클라이언트 목록을 기대하지만 실패합니다. 하나의 개체가 영업 담당자입니다.

검색과 관련하여 여러 가지 유사한 문제가 발생했지만 모두 구분 기호를 사용하는 것으로 보입니다. 각 하위 클래스에 대해 별도의 테이블이 있으며 GUID와 추가 속성 만 나열됩니다. 나는이 오류가 코드 오류로 hibernate (java)와 함께보고 된 것을 보았습니다. 그러나이 기사는 문제에 대한 깨진 링크가있는 Nhibernate 포트에서 수정되었다고 말했습니다.

Nhibernate API 쿼리는 가져와야 할 내 개체 유형을 지정하므로 다른 작업을 수행 할 수 있는지 잘 모르겠습니다. 신선한 쿼리를 강제 적용 할 수 있습니까?

실생활에서는 상황이 발생할 가능성이 거의 없지만 현재 상황에서는 내 로그인이 클라이언트와 영업 담당자가 될 수 없다는 점에 우려합니다. 응용 프로그램에서 더 큰 문제가 발생할 수 있습니다. 일부 다른 사람 유형이 사용됩니다. (각 유형에는 몇 가지 별도의 속성이 있습니다. 특정 유형의 사람을 지정하기 위해 분리 자 또는 사용자 역할을 사용하고 싶지 않습니다.)

아무런 조언을 주시면 감사하겠습니다.

아래 코드를 찾으십시오.

검색 방법 :

개체가 이미 라인에 영업 담당자로로드로드
public IEnumerable<Client> NewContacts(Guid userGUID) 
    { 
     SalesRepresentative rep = new SalesRepresentativeRepository().GetById(userGUID); 
     List<Client> result = new List<Client>(); 
     using (ISession session = NHibernateHelper.OpenSession()) 
     { 
      foreach (var i in rep.Projects) 
      { 
       ICriteria criteriaPerson = session.CreateCriteria(typeof(Client)); 
       criteriaPerson.CreateAlias("ProjectsOfInterest","p"); 
       criteriaPerson.Add(Expression.Eq("p.EntityGUID", i.EntityGUID)); 
       //Distinct 
       criteriaPerson.SetResultTransformer(new NHibernate.Transform.DistinctRootEntityResultTransformer()); 

       result.AddRange(criteriaPerson.List<Client>()); 
      } 
      return result.Distinct(); 
     } 
    } 

:

result.AddRange(criteriaPerson.List<Client>()); 

이유는 문제가 줄에

SalesRepresentative rep = new SalesRepresentativeRepository().GetById(userGUID); 

내 고객 중 하나가 영업 담당자입니다.

원래이 코드에는 프로젝트 주위에 루프가 없었지만 별칭을 통해 내부 조인이있었습니다. 이것은 쿼리에서 가져와 답변을 찾는 하나의 시도 였지만 동일한 결과가있었습니다.

    ICriteria criteriaPerson = session.CreateCriteria(typeof(Client)); 
       criteriaPerson.CreateAlias("ProjectsOfInterest", "p"); 
       criteriaPerson.CreateAlias("ProjectsOfInterest.SalesRepresentatives", "rep"); 
       criteriaPerson.Add(Expression.Eq("rep.EntityGUID", userGUID)); 

답변

1

오늘 (이 두 번째 실제로)이 동일한 오류에 빠졌습니다.

다른 ORM을 절충하지는 않지만 nHibernate를 사용하면 두 개의 다른 클래스 (하위 클래스)를 통해 ID를 공유 할 수 없습니다. 상속이 nHibernate에 있어야하는 방식이 아닙니다. 클래스 당 테이블 계층 구조는 부모 테이블을 지정하는 별도의 테이블을 가지고 있습니다.

클라이언트 나 직원에게 액세스하려면 실제로 사용자 ID를 참조해야합니다. (처음에는이 점에주의를 기울이지 않았지만 지금은 완전히 명확합니다.)

해결 방법은 도메인 모델을 리팩토링하고 클래스 간의 관계를 "is-a"관계에서 "has-a"관계로 변경하고 인터페이스를 통해 공통 속성 (필요한 경우)을 노출하는 것입니다.