NHibernate one-to-many mapping does not populate the bag
I have a simple object model of a header with multiple detail lines. I have mapped a bag property on the header object to the line class and also put a header property on the line class to set the two way relationship.
When I run my tests, using NHibernate Profiler I can see that the query is being performed, and the header and lines are fetched from the database, but the collection is always empty.
When I query for a collection of line objects directly I can get them and see the header object is correctly populated, so I know the mapping is probably OK.
The slightly non-standard aspect to this is that the line object has a compound key. (This is a legacy DB and I cannot change this), so I'm wondering if that is the problem.
Here are my classes and mappings (simplified)
<class name="Header" table="HEADER">
<id name="ID" column="HEAD_ID">
<generator class="assigned" />
</id>
<bag name="Lines" table="BODY" order-by="BODY_LINE">
<key column="BODY_HEADER_ID"/>
<one-to-many class="Line"/>
</bag>
</class>
<class name="Line" table="BODY">
<composite-id>
<key-property name="ID" column="BODY_HEADER_ID"/>
<key-property name="Line" column="SBODY_LINE"/>
</composite-id>
<many-to-one class="Header" name="Head" column="BODY_HEADER_ID" />
</class>
public class Header {
public virtual string ID { get; set; }
public virtual IList<Line> Lines { get; set; }
}
public class Line {
public virtual string ID { get; set; }
public virtual int Line { get; set; }
public virtual Header Head { get; set; }
public override bool Equals(object obj) {
var other = obj as Line;
return ID == other.ID && Line == other.Line;
}
public override int GetHashCode() {
return (ID + "|" + Line.ToString()).GetHashCode();
}
}
I can get around this by querying for the Line objects separately, but I'd like to know what I'm doing wrong.
EDIT: Ok, when I simplified things, I didn't do it very consistently. Sorry f开发者_运维百科or the confusion. I have changed the mapping and class definitions to reflect things more accurately.
You are mapping the same column twice (BODY_HEADER_ID), and using different three different class names for the HEADER table.
This is the correct Line mapping:
<class name="Line" table="BODY">
<composite-id>
<key-many-to-one class="Header" name="Header" column="BODY_HEADER_ID"/>
<key-property name="Line" column="SBODY_LINE"/>
</composite-id>
</class>
And of course, Line should have only that single reference to Header.
精彩评论