I referred to the following thread, which works with the session, but not with StatelessSession. NHibernate eagerly selects several levels
The problem I am facing is similar to the one described above. I return 4xApplications and 4xRoles. I have to return 1xApplication and 4xRoles.
Request criteria:
return StatelessSession.CreateCriteria(typeof(Application)) .SetResultTransformer(Transformers.DistinctRootEntity) .SetFetchMode("Roles", FetchMode.Join) .List<Application>();
My entities and mappings:
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