Hi!
I've got some headaches trying to use NHibernate with associations and collections. I'm totally new to NHib, having used my own "map tables to classes" functionality until now. NHibenate is very attractive though..
(Post Template information is below)
Anyway, here's my troubles:
1. When fetching A by criterias on children B, the one B that should match the criteria is not filled in the collection property of A. Is this by design? Do I have to fill A's property myself to get the one B I want? Does NHib. only fill collections when the entire child set is returned from the database?
The mapping below shows Part and CarPart, my criteria is set to fetch Parts where CarPart.X & CarPart.Y are equal to some values. The SQL returns the B I want, but it isn't mapped to the object.
Here's the criteria:
DetachedCriteria criteria = DetachedCriteria.For(typeof (Part));
DetachedCriteria subCrit = criteria.CreateAlias("CarParts", "CarParts");
criteria.Add(Expression.Eq("CarParts.CarId", 50));
criteria.Add(Expression.Eq("CarParts.PartGroupId", 106));
2. I have some associated classes not having exactly the same keys. IE. I have PartAttributes matching Part on PartId, CarPart on PartId and PartGroupId, but there's a third property on PartAttribute making it unique. (The three form a composite-id on PartAttribute)
When adding an association (bag) to Part where Part.PartId equals PartAttribute.PartId, I get 4 of each Part, but no PartAttributes in the mapped property. I also overloaded PartAttribute's Equals and HashCode methods making them compare and return an identity from PartAttribute, but no cigar. Ideally, I should get 12 Parts, with an average of 4 PartAttributes on each Part.
There are some lacking information from my code, but if you know the answer, I bet you don't need it ;)
Thanks in advance for any ideas and advice!
Lars-Erik
Hibernate version: 1.2 beta 3
Mapping documents:
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2">
<!-- ... -->
<class name="CarPartCatalog.Part, MarkedsPartner.CarPartCatalog.Contracts" table="Part">
<id name="PartId" column="PartId" type="int">
<generator class="identity" />
</id>
<property name="EartNumber" column="EARTNo"/>
<property name="Description" column="Description"/>
<property name="ManufacturerId" column="ManufacturerId" not-null="false"/>
<bag
name="Images"
collection-type="CarPartCatalog.PartImageCollection, MarkedsPartner.CarPartCatalog.Contracts"
lazy="false" fetch="join" cascade="none">
<key column="PartId"/>
<one-to-many class="CarPartCatalog.PartImage, MarkedsPartner.CarPartCatalog.Contracts"/>
</bag>
<bag
name="CarParts"
collection-type="CarPartCatalog.CarPartCollection, MarkedsPartner.CarPartCatalog.Contracts"
inverse="true"
lazy="false" fetch="join" cascade="none">
<key column="PartId"/>
<one-to-many class="CarPartCatalog.CarPart, MarkedsPartner.CarPartCatalog.Contracts"/>
</bag>
<bag
name="Attributes"
collection-type="CarPartCatalog.PartAttributeCollection, MarkedsPartner.CarPartCatalog.Contracts"
lazy="false" fetch="join" cascade="none">
<key column="PartId"/>
<one-to-many class="CarPartCatalog.PartAttribute, MarkedsPartner.CarPartCatalog.Contracts"/>
</bag>
<many-to-one
name="Manufacturer" column="ManufacturerId"
class="CarPartCatalog.Manufacturer, MarkedsPartner.CarPartCatalog.Contracts"
outer-join="true" lazy="false"/>
</class>
<!-- couple of irrelevant classes for this problem -->
<class name="CarPartCatalog.CarPart, MarkedsPartner.CarPartCatalog.Contracts" table="CarPart">
<id name="CarPartId" column="CarPartId" type="int">
<generator class="identity" />
</id>
<property name="PartId" column="PartId" not-null="true"/>
<property name="CarId" column="CarId" not-null="true"/>
<property name="PartGroupId" column="ProductGroupId" not-null="true"/>
<property name="CreatedDate" column="CreatedDate"/>
<property name="CreatedBy" column="CreatedBy"/>
<many-to-one
name="Part"
class="CarPartCatalog.Part, MarkedsPartner.CarPartCatalog.Contracts"
column="PartId"
foreign-key="PartId"
/>
<many-to-one
name="PartGroup"
class="CarPartCatalog.PartGroup, MarkedsPartner.CarPartCatalog.Contracts"
column="ProductGroupId"
foreign-key="PartGroupId"
/>
</class>
<class name="CarPartCatalog.PartAttribute, MarkedsPartner.CarPartCatalog.Contracts" table="PartAttributes">
<composite-id>
<key-property name="PartId"/>
<key-property name="PartGroupId"/>
<key-property name="AttributeTypeId" column="AttributeTypeId"/>
</composite-id>
<property name="Value" column="Value"/>
<property name="PartAttributeId" unique="true"/>
<many-to-one
name="AttributeType" column="AttributeTypeId"
class="CarPartCatalog.AttributeType, MarkedsPartner.CarPartCatalog.Contracts"
outer-join="true" lazy="false" fetch="join"/>
<many-to-one
name="AttributeValue"
class="CarPartCatalog.AttributeValue, MarkedsPartner.CarPartCatalog.Contracts"
outer-join="true" lazy="false" not-found="ignore" fetch="join">
<column name="AttributeTypeId"/>
<column name="Value"/>
</many-to-one>
</class>
</hibernate-mapping>
Code between sessionFactory.openSession() and session.close():
// See top for real criteria ;)
ICriteria crit = query.GetExecutableCriteria(session);
crit.List(list);
Full stack trace of any exception that occurs:
Name and version of the database you are using:
The generated SQL (show_sql=true):
exec sp_executesql N'SELECT this_.PartId as PartId0_5_, this_.EARTNo as EARTNo0_5_, this_.Description as Descript3_0_5_, this_.ManufacturerId as Manufact4_0_5_, images3_.PartId as PartId__7_, images3_.ImageId as ImageId7_, images3_.ImageId as ImageId1_0_,
images3_.PartId as PartId1_0_, images3_.ImageName as ImageName1_0_, carparts1_.CarPartId as CarPartId9_1_, carparts1_.PartId as PartId9_1_, carparts1_.CarId as CarId9_1_, carparts1_.ProductGroupId as ProductG4_9_1_, carparts1_.CreatedDate as CreatedD5_9_1_,
carparts1_.CreatedBy as CreatedBy9_1_, partgroup5_.PartGroupId as PartGrou1_15_2_, partgroup5_.ParentPartGroupId as ParentPa2_15_2_, partgroup5_.Name as Name15_2_, partgroup6_.PartGroupId as PartGrou1_15_3_, partgroup6_.ParentPartGroupId as ParentPa2_15_3_,
partgroup6_.Name as Name15_3_, manufactur7_.ManufacturerId as Manufact1_7_4_, manufactur7_.Name as Name7_4_ FROM Part this_ left outer join PartImages images3_ on this_.PartId=images3_.PartId inner join CarPart carparts1_ on this_.PartId=carparts1_.PartId left outer
join PartGroup partgroup5_ on carparts1_.ProductGroupId=partgroup5_.PartGroupId left outer join PartGroup partgroup6_ on partgroup5_.ParentPartGroupId=partgroup6_.PartGroupId left outer join Manufacturer manufactur7_ on this_.ManufacturerId=manufactur7_.ManufacturerId
WHERE carparts1_.CarId = @p0 and carparts1_.ProductGroupId = @p1',N'@p0 int,@p1 int',@p0=50,@p1=106
Debug level Hibernate log excerpt:
|