V important ICrteria Question

<[email protected]> Wed, 20 Aug 2008 16:09:17 +1000
Newsgroups gmane.comp.windows.dotnet.nhibernate.devel
Message-ID <[email protected]>
Hi Everyone 

I am relatively new to Nhibernate. I have been trying to do something
using Criteria objects and have found it very hard to do. It's a
relatively simple thing to do using HQL or Sql but we prefer Criteria
objects as they retain the mappings. 

The problem: 

I need to check whether a particular user has a particular role. I try
to do the following 

using (NHibernate.ISession session =
NHibernateSessionManager.Instance.GetSession<UserRelationship>(appSessio
n)) 
            { 
                ICriteria criteria =
session.CreateCriteria(typeof(UserRelationship)); 
                criteria.CreateCriteria("User", "usr",
JoinType.LeftOuterJoin); 
                criteria.Add(Expression.Eq("usr.Id", userId)); 
                criteria.CreateCriteria("ExternalRole", "ex",
JoinType.LeftOuterJoin); 
                criteria.Add(Expression.Eq("ex.Name", roleName)); 
                relationshipList = criteria.List<UserRelationship>();

          
                               

            } 

but that gives me following error: System.Data.SqlClient.SqlException:
The correlation name 'ex1_' is specified multiple times in a FROM
clause.

 It works fine when I run the criteria for
ClientExternalRoleRelationship as it doesn't have to join to the
ExternalRole table twice but because UserRelationship is a base class
for ExternalRoleRelationship and ClientExternalRoleRelationship . How do
I tell it not to use same alias twice but to use a different one for
each join? I even tried FetchMode.Join etc with the "Role" in the
association Path. That works fine but if I then try and provide a filter
on the Role object to check for a particluar RoleName nhibernate doesn't
like it and thinks that I am accessing a property on the root object
(UserRelationship)

Help will be greatly appreciated. 

The mapping files are attached 

                                                      .

Classification: UNCLASSIFIED


 <<UserRelationship.hbm.xml>>  <<ExternalUserRelationships.hbm.xml>>  
<<InternalUserRelationships.hbm.xml>>  <<ProgrammeRole.hbm.xml>>  
<<Role.hbm.xml>>  <<User.hbm.xml>>

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/

_______________________________________________
Nhibernate-development mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/nhibernate-development
UserRelationship.hbm.xml (text/xml, 2.4 KB)
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
    <class name="GrantEd.DomainModel.UserMgmt.UserRelationship, GrantEd.DomainModel.UserMgmt" table="UserRelationship" select-before-update="true" schema="UserMgmt" >

        <id name="Id" type="Int32" unsaved-value="0" access="property" >
            <column name="Id" length="4" sql-type="int" not-null="true" unique="true"/>
            <generator class="identity" />
        </id>
        
        <version name="RowVersion" column="RowVersion" type="Int64" access="property" />


        <component name="Created" class="GrantEd.Common.DomainModel.Audit, GrantEd.Common.DomainModel">
            <property name="ActionDate" column="CreatedActionDate" type="DateTime" not-null="true"/>
            <many-to-one name="ActionUser" class="GrantEd.Common.DomainModel.UserSummary, GrantEd.Common.DomainModel" lazy="false">
                <column name="CreatedActionUser" length="4" sql-type="int" not-null="true"/>
            </many-to-one>
        </component>

        <component name="LastUpdated" class="GrantEd.Common.DomainModel.Audit, GrantEd.Common.DomainModel">
            <property name="ActionDate" column="LastUpdatedActionDate" type="DateTime" not-null="true"/>
            <many-to-one name="ActionUser" class="GrantEd.Common.DomainModel.UserSummary, GrantEd.Common.DomainModel" lazy="false">
                <column name="LastUpdatedActionUser" length="4" sql-type="int" not-null="true"/>
            </many-to-one>
        </component>


        <many-to-one name="User" class="GrantEd.DomainModel.UserMgmt.User, GrantEd.DomainModel.UserMgmt.User" 
                     cascade="none" lazy="proxy" fetch="join">
            <column name="UserId" length="4" sql-type="int" not-null="true"/>
        </many-to-one>
        
        <property name="IsDeleted" type="Boolean">
            <column name="IsDeleted" length="1" sql-type="bit" not-null="false"/>
        </property>

        <many-to-one name="UserRelationshipTypeCode" class="GrantEd.Common.DomainModel.Code.UserRelationshipTypeCode, GrantEd.Common.DomainModel.Code" 
                     cascade="none" lazy="false" fetch="join" access="nosetter.camelcase-underscore">
            <column name="UserRelationshipTypeCodeId" length="4" sql-type="int" not-null="true"/>
        </many-to-one>

    </class>
</hibernate-mapping>
ExternalUserRelationships.hbm.xml (text/xml, 2.6 KB)
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
    <!-- External Role Relationship Sub Class -->
    <joined-subclass name="GrantEd.DomainModel.UserMgmt.ExternalRoleRelationship, GrantEd.DomainModel.UserMgmt" table="ExternalRoleRelationship" schema="UserMgmt"
                     extends="GrantEd.DomainModel.UserMgmt.UserRelationship, GrantEd.DomainModel.UserMgmt">
        <key>
            <column name="Id" length="4" sql-type="int" not-null="true" unique="true"/>
        </key>

        <many-to-one name="ExternalRole" class="GrantEd.DomainModel.UserMgmt.ExternalRole, GrantEd.DomainModel.UserMgmt" fetch="join" lazy="false">
            <column name="ExternalRoleId" length="4" sql-type="int" not-null="false"/>
        </many-to-one>

    </joined-subclass>

    <!-- Client External Role Relationship Sub Class -->
    <joined-subclass name="GrantEd.DomainModel.UserMgmt.ClientExternalRoleRelationship, GrantEd.DomainModel.UserMgmt" table="ClientExternalRoleRelationship" schema="UserMgmt"
                     extends="GrantEd.DomainModel.UserMgmt.UserRelationship, GrantEd.DomainModel.UserMgmt">
        <key>
            <column name="Id" length="4" sql-type="int" not-null="true" unique="true"/>
        </key>

        <component name="Client" class="GrantEd.DomainModel.Client.Client, GrantEd.DomainModel.Client" >
            <property name="Id" column="ClientId"  type="Int32" not-null="true" />
        </component>

        <many-to-one name="ExternalRole" class="GrantEd.DomainModel.UserMgmt.ExternalRole, GrantEd.DomainModel.UserMgmt" fetch="join" lazy="false">
            <column name="ExternalRoleId" length="4" sql-type="int" not-null="false"/>
        </many-to-one>

        <!--TODO Audit-->
    </joined-subclass>

  <joined-subclass name="GrantEd.DomainModel.UserMgmt.ClientProgrammeRoleRelationship, GrantEd.DomainModel.UserMgmt" table="ClientProgrammeRoleRelationship" schema="UserMgmt"
                     extends="GrantEd.DomainModel.UserMgmt.UserRelationship, GrantEd.DomainModel.UserMgmt">
    <key>
      <column name="Id" length="4" sql-type="int" not-null="true" unique="true"/>
    </key>

    <component name="Client" class="GrantEd.DomainModel.Client.Client, GrantEd.DomainModel.Client" >
      <property name="Id" column="ClientId"  type="Int32" not-null="true" />
    </component>

    <many-to-one name="ProgrammeRole" class="GrantEd.DomainModel.UserMgmt.ProgrammeRole, GrantEd.DomainModel.UserMgmt" lazy="false">
      <column name="ProgrammeRoleId" length="4" sql-type="int" not-null="false"/>
    </many-to-one>

    
  </joined-subclass>

</hibernate-mapping>
InternalUserRelationships.hbm.xml (text/xml, 1.6 KB)
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
    <!-- Internal Role Relationship Sub Class -->
    <joined-subclass name="GrantEd.DomainModel.UserMgmt.InternalRoleRelationship, GrantEd.DomainModel.UserMgmt" table="InternalRoleRelationship"
                     schema="UserMgmt"
                     extends="GrantEd.DomainModel.UserMgmt.UserRelationship, GrantEd.DomainModel.UserMgmt">
        <key>
            <column name="Id" length="4" sql-type="int" not-null="true" unique="true"/>
        </key>

        <many-to-one name="InternalRole" class="GrantEd.DomainModel.UserMgmt.InternalRole, GrantEd.DomainModel.UserMgmt" lazy="false" >
            <column name="InternalRoleId" length="4" sql-type="int" not-null="false"/>
        </many-to-one>

        <!--TODO Audit-->
    </joined-subclass>

    <!-- Programme Internal Role Relationship Sub Class -->
    <joined-subclass name="GrantEd.DomainModel.UserMgmt.ProgrammeRoleRelationship, GrantEd.DomainModel.UserMgmt" table="ProgrammeRoleRelationship"
                     schema="UserMgmt"
                     extends="GrantEd.DomainModel.UserMgmt.UserRelationship, GrantEd.DomainModel.UserMgmt">
        <key>
            <column name="Id" length="4" sql-type="int" not-null="true" unique="true"/>
        </key>       
        <many-to-one name="ProgrammeRole" class="GrantEd.DomainModel.UserMgmt.ProgrammeRole, GrantEd.DomainModel.UserMgmt" lazy="false">
                    <column name="ProgrammeRoleId" length="4" sql-type="int" not-null="false"/>
        </many-to-one>
        <!--TODO Audit-->
    </joined-subclass>
</hibernate-mapping>
ProgrammeRole.hbm.xml (text/xml, 2.2 KB)
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
    <class name="GrantEd.DomainModel.UserMgmt.ProgrammeRole, GrantEd.DomainModel.UserMgmt" table="ProgrammeRole" select-before-update="true" schema="UserMgmt" >

        <id name="Id" type="Int32" unsaved-value="0" access="property" >
            <column name="Id" length="4" sql-type="int" not-null="true" unique="true"/>
            <generator class="identity" />
        </id>
        
        <version name="RowVersion" column="RowVersion" type="Int64" access="property" />


        <component name="Created" class="GrantEd.Common.DomainModel.Audit, GrantEd.Common.DomainModel">
            <property name="ActionDate" column="CreatedActionDate" type="DateTime" not-null="true"/>
            <many-to-one name="ActionUser" class="GrantEd.Common.DomainModel.UserSummary, GrantEd.Common.DomainModel" lazy="false">
                <column name="CreatedActionUser" length="4" sql-type="int" not-null="true"/>
            </many-to-one>
        </component>

        <component name="LastUpdated" class="GrantEd.Common.DomainModel.Audit, GrantEd.Common.DomainModel">
            <property name="ActionDate" column="LastUpdatedActionDate" type="DateTime" not-null="true"/>
            <many-to-one name="ActionUser" class="GrantEd.Common.DomainModel.UserSummary, GrantEd.Common.DomainModel" lazy="false">
                <column name="LastUpdatedActionUser" length="4" sql-type="int" not-null="true"/>
            </many-to-one>
        </component>


        <property name="IsDeleted" type="Boolean">
        <column name="IsDeleted" length="1" sql-type="bit" not-null="false"/>
      </property>      

      <component name="Programme" class="GrantEd.DomainModel.Programme.Programme, GrantEd.DomainModel.Programme">
        <property name="Id" column="ProgrammeId" type="Int32" not-null="true" />
      </component>
      
      <many-to-one name="Role" class="GrantEd.DomainModel.UserMgmt.Role, GrantEd.DomainModel.UserMgmt" lazy="false">
        <column name="RoleId" length="4" sql-type="int" not-null="false"/>
      </many-to-one>
      

    </class>
</hibernate-mapping>
Role.hbm.xml (text/xml, 3.3 KB)
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
    <class name="GrantEd.DomainModel.UserMgmt.Role, GrantEd.DomainModel.UserMgmt" table="`Role`" select-before-update="true" schema="UserMgmt">

        <id name="Id" type="Int32" unsaved-value="0" access="property" >
            <column name="Id" length="4" sql-type="int" not-null="true" unique="true"/>
            <generator class="identity"/>
        </id>
        <discriminator column="RoleTypeCodeId" length="4" type="String" not-null="true"></discriminator>
        <version name="RowVersion" column="RowVersion" type="Int64" access="property" />


        <component name="Created" class="GrantEd.Common.DomainModel.Audit, GrantEd.Common.DomainModel">
            <property name="ActionDate" column="CreatedActionDate" type="DateTime" not-null="true"/>
            <many-to-one name="ActionUser" class="GrantEd.Common.DomainModel.UserSummary, GrantEd.Common.DomainModel" lazy="false">
                <column name="CreatedActionUser" length="4" sql-type="int" not-null="true"/>
            </many-to-one>
        </component>

        <component name="LastUpdated" class="GrantEd.Common.DomainModel.Audit, GrantEd.Common.DomainModel">
            <property name="ActionDate" column="LastUpdatedActionDate" type="DateTime" not-null="true"/>
            <many-to-one name="ActionUser" class="GrantEd.Common.DomainModel.UserSummary, GrantEd.Common.DomainModel" lazy="false">
                <column name="LastUpdatedActionUser" length="4" sql-type="int" not-null="true"/>
            </many-to-one>
        </component>


        <property name="Code" type="String">
            <column name="Code" length="50" sql-type="varchar" not-null="true" unique="true" index="UQ_Role_Code"/>
        </property>
        <property name="Name" type="String">
            <column name="Name" length="50" sql-type="varchar" not-null="true" unique="true" index="UQ_Role_Name"/>
        </property>
        <property name="Description" type="String">
            <column name="Description" sql-type="varchar" not-null="false"/>
        </property>
        <property name="IsDeleted" type="Boolean">
            <column name="IsDeleted" length="1" sql-type="bit" not-null="false"/>
        </property>

        <!--<many-to-one name="RoleTypeCode" class="GrantEd.Common.DomainModel.Code.RoleTypeCode, GrantEd.Common.DomainModel.Code" cascade="none" lazy="false" fetch="join">
            <column name="RoleTypeCodeId" length="4" sql-type="int" not-null="true"/>
        </many-to-one>-->

        <!-- Internal Role -->
        <subclass name="GrantEd.DomainModel.UserMgmt.InternalRole, GrantEd.DomainModel.UserMgmt" discriminator-value="1" dynamic-insert="true" dynamic-update="true" >
            <!--<key>
                <column name="Id" length="4" sql-type="int" not-null="true" unique="true"/>
            </key>-->
        </subclass>

        <!-- External Role -->
      <subclass name="GrantEd.DomainModel.UserMgmt.ExternalRole, GrantEd.DomainModel.UserMgmt" discriminator-value="2" dynamic-insert="true" dynamic-update="true">
            <!--<key>
                <column name="Id" length="4" sql-type="int" not-null="true" unique="true"/>
            </key>-->
        </subclass>

    </class>
</hibernate-mapping>
User.hbm.xml (text/xml, 5.8 KB)
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
    <class name="GrantEd.DomainModel.UserMgmt.User, GrantEd.DomainModel.UserMgmt.User" table="`User`" select-before-update="true" schema="Utility" >

        <id name="Id" type="Int32" unsaved-value="0" access="property" >
            <column name="Id" length="4" sql-type="int" not-null="true" unique="true"/>
            <generator class="identity" />
        </id>

        <version name="RowVersion" column="RowVersion" type="Int64" access="property" />


        <component name="Created" class="GrantEd.Common.DomainModel.Audit, GrantEd.Common.DomainModel">
            <property name="ActionDate" column="CreatedActionDate" type="DateTime" not-null="true"/>
            <many-to-one name="ActionUser" class="GrantEd.Common.DomainModel.UserSummary, GrantEd.Common.DomainModel" lazy="false">
                <column name="CreatedActionUser" length="4" sql-type="int" not-null="true"/>
            </many-to-one>
        </component>

        <component name="LastUpdated" class="GrantEd.Common.DomainModel.Audit, GrantEd.Common.DomainModel">
            <property name="ActionDate" column="LastUpdatedActionDate" type="DateTime" not-null="true"/>
            <many-to-one name="ActionUser" class="GrantEd.Common.DomainModel.UserSummary, GrantEd.Common.DomainModel" lazy="false">
                <column name="LastUpdatedActionUser" length="4" sql-type="int" not-null="true"/>
            </many-to-one>
        </component>


        <many-to-one name="UserTypeCode" class="GrantEd.Common.DomainModel.Code.UserTypeCode, GrantEd.Common.DomainModel.Code" cascade="none" lazy="false" fetch="join">
            <column name="UserTypeCodeId" length="4" sql-type="int" not-null="true"/>
        </many-to-one>
        <many-to-one name="DomainTypeCode" class="GrantEd.Common.DomainModel.Code.DomainTypeCode, GrantEd.Common.DomainModel.Code" cascade="none" lazy="false" fetch="join">
            <column name="DomainTypeCodeId" length="4" sql-type="int" not-null="true"/>
        </many-to-one>        
        <component name="Individual" class="GrantEd.DomainModel.Party.Individual, GrantEd.DomainModel.Party">
          <property column="IndividualId" name="Id" type="Int32" not-null="true"/>
        </component>
        <property name="IsSystemUser" type="Boolean">
            <column name="IsSystemUserFlag" length="1" sql-type="bit" not-null="true"/>
        </property>
        <property name="UserName" type="String">
            <column name="UserName" length="50" sql-type="varchar" not-null="true"/>
        </property>
        <!--This property bag can't exist here because the user class can't containt the UserRequest type without creating a circular ref-->
        <!--<bag name="UserRequests" collection-type="GrantEd.DomainModel.UserMgmt.UserRequests, GrantEd.DomainModel.UserMgmt"
                                  access="property" inverse="true" cascade="all-delete-orphan">
          <key column="UserRequestId"/>
          <one-to-many class="GrantEd.DomainModel.UserMgmt.UserRequest, GrantEd.DomainModel.UserMgmt"/>
        </bag>-->
      
        <!-- Internal User -->
        <joined-subclass name="GrantEd.DomainModel.UserMgmt.InternalUser, GrantEd.DomainModel.UserMgmt" table="InternalUser" schema="UserMgmt"
                         select-before-update="false">
            <key>
                <column name="Id" length="4" sql-type="int" not-null="true" unique="true"/>
            </key>

            <bag name="Relationships" collection-type="GrantEd.DomainModel.UserMgmt.UserRelationshipsUserType, GrantEd.DomainModel.UserMgmt"
                access="property" inverse="true" cascade="all">
                <key column="UserId"/>
                <one-to-many class="GrantEd.DomainModel.UserMgmt.UserRelationship, GrantEd.DomainModel.UserMgmt"/>
            </bag>
          <!-- Bitcrafted By Tiggr 16/1/2008 Changes made by rob have meant that the only value for cascade that works here is "ALL" :S -->
          <bag name="UserRequests" collection-type="GrantEd.DomainModel.UserMgmt.UserRequestsUserType, GrantEd.DomainModel.UserMgmt"
                          access="property" inverse="true" cascade="all">
            <key column="UserRequestId"/>
            <one-to-many class="GrantEd.DomainModel.UserMgmt.UserRequest, GrantEd.DomainModel.UserMgmt"/>
          </bag>
        </joined-subclass>

        <!-- External User -->
        <joined-subclass name="GrantEd.DomainModel.UserMgmt.ExternalUser, GrantEd.DomainModel.UserMgmt" table="ExternalUser" schema="UserMgmt"
                         select-before-update="false">
            <key>
                <column name="Id" length="4" sql-type="int" not-null="true" unique="true"/>
            </key>
            <many-to-one name="Registration" class="GrantEd.DomainModel.UserMgmt.Registration, GrantEd.DomainModel.UserMgmt" cascade="all" fetch="join">
                <column name="RegistrationId" length="4" sql-type="int" not-null="true"/>
            </many-to-one>

            <bag name="Relationships" collection-type="GrantEd.DomainModel.UserMgmt.UserRelationshipsUserType, GrantEd.DomainModel.UserMgmt"
                access="property" inverse="true" cascade="all">
                <key column="UserId"/>
                <one-to-many class="GrantEd.DomainModel.UserMgmt.UserRelationship, GrantEd.DomainModel.UserMgmt"/>
            </bag>
            <bag name="UserRequests" collection-type="GrantEd.DomainModel.UserMgmt.UserRequestsUserType, GrantEd.DomainModel.UserMgmt"
                access="property" inverse="true" cascade="all">
                <key column="UserId"/>
                <one-to-many class="GrantEd.DomainModel.UserMgmt.UserRequest, GrantEd.DomainModel.UserMgmt"/>
            </bag>

        </joined-subclass>

    </class>
</hibernate-mapping>