2010-02-23 3 views
4

세션과는 작동하지만 StatelessSession은 사용하지 않는 다음 스레드를 참조했다. NHibernate Eager Fetching Over Multiple LevelsHibernate Eager는 StatelessSession을 사용하여 여러 레벨을 가져왔다.

내가 겪고있는 문제는 위의 스레드와 유사합니다. 4xApplications 및 4xRoles가 다시 나타납니다. 나는 1xApplication과 4xRoles를 돌려 받게 될 것입니다.

기준 쿼리 :

return StatelessSession.CreateCriteria(typeof(Application)) 
      .SetResultTransformer(Transformers.DistinctRootEntity) 
      .SetFetchMode("Roles", FetchMode.Join) 
      .List<Application>(); 

내 기업 및 매핑 :

public class Application : IComparable<Application> 
{ 
    public virtual int Id { get; set; } 
    public virtual string InternalName { get; set; } 
    public virtual ICollection<Role> Roles { get; set; } 

    #region IComparable<Application> Members 

    public virtual int CompareTo(Application other) 
    { 
     return Id.CompareTo(other.Id); 
    } 

    #endregion 

}

public class Role : IComparable<Role> 
{ 
    public virtual int Id { get; set; } 
    public virtual string Name { get; set; } 
    public virtual Application Application { get; set; } 

    public virtual int CompareTo(Role other) 
    { 
     return Id.CompareTo(other.Id); 
    } 

}

public class ApplicationMapping : ClassMap<Application> 
{ 
    public ApplicationMapping() 
    { 
     Table("Application"); 
     Id(x => x.Id, "ID").GeneratedBy.Assigned(); ; //.Column("ID"); 
     Map(x => x.InternalName); 
     HasMany(x => x.Roles).Inverse().Cascade.All().AsSet().Not.LazyLoad(); 
    } 
} 

public class RoleMapping : ClassMap<Role> 
{ 
    public RoleMapping() 
    { 

     Table("Roles"); 
     Id(x => x.Id, "ID").GeneratedBy.Assigned(); 
     References(x => x.Application, "ApplicationID").Not.LazyLoad(); 
     Map(x => x.Name); 
     HasMany(x => x.RightsUsers).Table("UserRoleXRef").Inverse().Cascade.All().AsSet(); 
    } 
} 

hbm.xml

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access="property"  auto-import="true" default-cascade="none" default-lazy="true"> 
    <class xmlns="urn:nhibernate-mapping-2.2" name="Quad.App.Test.DataAccess.NHibernate.Scaffolding.Entities.Application, Quad.App.Test, Version=1.4.0.742, Culture=neutral, PublicKeyToken=null" table="Application"> 
<id name="Id" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> 
    <column name="ID" /> 
    <generator class="assigned" /> 
</id> 
<property name="InternalName" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> 
    <column name="InternalName" /> 
</property> 
<set cascade="all" inverse="true" lazy="false" name="Roles"> 
    <key> 
    <column name="ApplicationID" /> 
    </key> 
    <one-to-many class="Quad.App.Test.DataAccess.NHibernate.Scaffolding.Entities.Role, Quad.App.Test, Version=1.4.0.742, Culture=neutral, PublicKeyToken=null" /> 
</set> 
    </class> 
</hibernate-mapping> 

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" default-access="property"  auto-import="true" default-cascade="none" default-lazy="true"> 
    <class xmlns="urn:nhibernate-mapping-2.2" name="Quad.App.Test.DataAccess.NHibernate.Scaffolding.Entities.Role, Quad.App.Test, Version=1.4.0.742, Culture=neutral, PublicKeyToken=null" table="Roles"> 
<id name="Id" type="System.Int32, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> 
    <column name="ID" /> 
    <generator class="assigned" /> 
</id> 
<property name="Name" type="System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> 
    <column name="Name" /> 
</property> 
<many-to-one class="Quad.App.Test.DataAccess.NHibernate.Scaffolding.Entities.Application, Quad.App.Test, Version=1.4.0.742, Culture=neutral, PublicKeyToken=null" lazy="false" name="Application"> 
    <column name="ApplicationID" /> 
</many-to-one> 
    </class> 
</hibernate-mapping> 

SQL :

SELECT this_.ID as ID1_1_, 
this_.InternalName as Internal2_1_1_, 
roles2_.ApplicationID as Applicat3_3_, 
roles2_.ID as ID3_, 
roles2_.ID as ID2_0_, 
roles2_.Name as Name2_0_, 
roles2_.ApplicationID as Applicat3_2_0_ 
FROM dbo.Application this_ left outer join dbo.Roles roles2_ on  
this_.ID=roles2_.ApplicationID 
+0

이상한. 역할을 비 게으름으로 매핑 한 것을 이미 알고 있습니까? FetchMode가 두 번 듣는 것을 좋아하지 않는지 궁금합니다. SetFetchMode를 제거하면, 지연되지 않는 방법은 무엇입니까? 외부 조인 또는 선택? – dotjoe

+0

그러면 역할 목록을 지연로드 할 수 없다는 예외가 발생합니다. 응용 프로그램 테이블에서 선택합니다. this_.ID를 ID1_0_으로, this_.InternalName을 Internal2_1_0_에서 dbo.Application으로 변경하십시오. { "[Quad.App.Test.DataAccess.NHibernate.Scaffolding.Entities.Application # 50]을 초기화하면 { 역할 : Quad.App.Test.DataAccess.NHibernate.Scaffolding.Entities.Application.Roles, 세션이나 세션이 닫히지 않았습니다. "} – magellings

답변

0

나는 SQL 쿼리가 역할이 합류했다으로 중복 애플리케이션을 생성 생성하기 때문입니다 생각한다.

이 문제를 피하는 가장 간단한 방법은 ICollection (Iesi.Collections.dll에 정의 됨) 대신 ISet (HashedSet <> 구현)을 사용하는 것입니다. 이는 목록에서 중복되지 않도록 설계되었습니다.

관련 문제