Hi
I have a collection in an entity mapped as a many-to-many relationship. The entities in the collection are of type AccessCountry, which is a subclass of AccessRule. I am using the table-per-class-hierarchy strategy for my subclasses. I want to ensure that this collection only contains entities of type AccessCountry so I attempted to use the "where" clause to reference the discriminator column, "Type" like so:
Code:
<set name="AccessCountries"
table="`AccessRuleUserAssoc`"
lazy="true"
sort="VendorUserAccessCountrySorter"
where="Type = 'AccessCountry'"
>
<key column="VendorUserUid" />
<many-to-many class="AccessCountry" column="AccessRuleId" />
</set>
Unfortunately the "where" clause seems to apply to the association table, "AccessRuleUserAssoc" and so the query fails as the Type column does not exist in this table.
If I don't include the "where" clause my collection contains other entities derived from AccessRule but not of type AccessCountry.
What have I got wrong here? Any help much appreciated!
Hibernate version:1.2.0.4
Mapping documents:Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<class name="AccessRule" table="`AccessRule`" discriminator-value="AccessRule">
<meta attribute="class-description"></meta>
<id name="AccessRuleId" column="AccessRuleId" type="Guid" unsaved-value="{00000000-0000-0000-0000-000000000000}">
<meta attribute="field-description"></meta>
<generator class="guid.comb"/>
</id>
<discriminator column="Type" />
<version name="Version" column="Version" type="Int32" />
<property name="Name" column="Name" type="String" not-null="true" length="255">
<meta attribute="field-description"></meta>
</property>
<many-to-one name="AccessRuleGroup" class="AccessRuleGroup" column="AccessRuleGroupId" />
</class>
</hibernate-mapping>
Code:
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<subclass name="AccessCountry" extends="AccessRule" discriminator-value="AccessCountry">
<property name="CountryCode" column="CountryCode" type="String" not-null="false" length="5">
<meta attribute="field-description"></meta>
</property>
<property name="GlobalContent" column="GlobalContent" type="Boolean" not-null="true" >
<meta attribute="field-description"></meta>
</property>
<property name="Internal" column="`Internal`" type="Boolean" not-null="true" >
<meta attribute="field-description"></meta>
</property>
</subclass>
</hibernate-mapping>
The following fails because "Type" is a column in AccessRule table, not AccessRuleUserAssoc.
Code:
<set name="AccessCountries"
table="`AccessRuleUserAssoc`"
lazy="true"
sort="VendorUserAccessCountrySorter"
where="Type = 'AccessCountry'"
>
<key column="VendorUserUid" />
<many-to-many class="AccessCountry" column="AccessRuleId" />
</set>
Name and version of the database you are using:Sql 2005
The generated SQL :Code:
exec sp_executesql N'SELECT accesscoun0_.VendorUserUid as VendorUs2___1_, accesscoun0_.AccessRuleId as AccessRu1_1_, accesscoun1_.AccessRuleId as AccessRu1_40_0_, accesscoun1_.CountryCode as CountryC6_40_0_, accesscoun1_.GlobalContent as GlobalCo7_40_0_,
accesscoun1_.[Internal] as Internal8_40_0_, accesscoun1_.AccessDivisionId as AccessDi9_40_0_, accesscoun1_.Version as Version40_0_, accesscoun1_.Name as Name40_0_, accesscoun1_.AccessRuleGroupId as AccessRu5_40_0_ FROM [AccessRuleUserAssoc] accesscoun0_ left outer join
[AccessRule] accesscoun1_ on accesscoun0_.AccessRuleId=accesscoun1_.AccessRuleId WHERE accesscoun0_.Type = ''AccessCountry'' and accesscoun0_.VendorUserUid=@p0',N'@p0 uniqueidentifier',@p0='C81BC473-3F81-4CA0-9E6B-823735317F27'
Debug level Hibernate log excerpt:Code:
TemplateExpertTests.TestLoadUserWithAccessCountries : NHibernate.LazyInitializationException : Failed to lazily initialize a collection
----> NHibernate.ADOException : could not initialize a collection: [AccessCountries#c81bc473-3f81-4ca0-9e6b-823735317f27][SQL: SELECT accesscoun0_.VendorUserUid as VendorUs2___1_, accesscoun0_.AccessRuleId as AccessRu1_1_, accesscoun1_.AccessRuleId as AccessRu1_40_0_, accesscoun1_.CountryCode as CountryC6_40_0_, accesscoun1_.GlobalContent as GlobalCo7_40_0_, accesscoun1_.[Internal] as Internal8_40_0_, accesscoun1_.AccessDivisionId as AccessDi9_40_0_, accesscoun1_.Version as Version40_0_, accesscoun1_.Name as Name40_0_, accesscoun1_.AccessRuleGroupId as AccessRu5_40_0_ FROM [AccessRuleUserAssoc] accesscoun0_ left outer join [AccessRule] accesscoun1_ on accesscoun0_.AccessRuleId=accesscoun1_.AccessRuleId WHERE accesscoun0_.Type = 'AccessCountry' and accesscoun0_.VendorUserUid=?]
----> System.Data.SqlClient.SqlException : Invalid column name 'Type'.