Reputation: 6660
I am trying to map a relaitively simple data model with NHibernate for use with breeze.js. The data model consists of four entities and looks like this:
The problem seems to be with the relationship between the CourseDate
and the CourseDateStudent
entity. When calling the Metdata
method of my BreezeController I get the following error:
System.ArgumentException: "Could not find matching fk for property HR.CourseManager.Web.Data.Entities.CourseDateStudent.CourseDate"
I do not know what exactly causes this behavior as I think I have implemented my model as recommended by the breeze.js documentation.
There is another question convering a somewhat similar topic, but this question does not address having composite keys.
(Remark: Adding surrogate keys like numeric ids is not an option here. As you might have guessed this is not the real data model but one that simply has had its entities renamed. The underlying database is used by a whole bunch of applications and cannot be changed.)
Enough of writing about my problem. Let's see some code! So there is the CourseDate
entity which has a composite key consisting of the properties CourseCode
and Date
:
CourseDate.cs:
public class CourseDate {
public CourseDate() {
this.Students = new List<CourseDateStudent>();
}
public virtual Course Course { get; set; }
public virtual DateTime Date { get; set; }
public virtual string CourseCode { get; set; }
public virtual ICollection<CourseDateStudent> Students { get; set; }
// Skipped implementation of Equals and GetHashCode for readability
}
CourseDate.hbm.xml:
<hibernate-mapping assembly="CourseManager.Web"
namespace="CourseManager.Web.Data.Entities"
xmlns="urn:nhibernate-mapping-2.2">
<class name="CourseDate" table="COURSE_DT" lazy="true" >
<composite-id>
<key-many-to-one name="Course" column="COURSE_CODE" />
<key-property name="Date" column="DT" />
</composite-id>
<property name="CourseCode" insert="false" update="false">
<column name="COURSE_CODE" sql-type="VARCHAR2" not-null="true" />
</property>
<bag name="Students" inverse="true">
<key>
<column name="COURSE_CODE" />
<column name="COURSE_DT" />
</key>
<one-to-many class="CourseDateStudent" />
</bag>
</class>
</hibernate-mapping>
And then there is the CourseDateStudent
entity that has a primary key consisting of the CourseCode
and the CourseDate
property (thus defining the foreign key relationship to the CourseDate
entity) as well as the StudentId
property:
CourseDateStudent.cs
public class CourseDateStudent {
public virtual CourseDate CourseDate { get; set; }
public virtual Student Student { get; set; }
public virtual long StudentId { get; set; }
public virtual string CourseCode { get; set; }
public virtual DateTime Date { get; set; }
// Skipped implementation of Equals and GetHashCode for readability
}
CourseDateStudent.hbm.xml
<hibernate-mapping assembly="CourseManager.Web"
namespace="CourseManager.Web.Data.Entities"
xmlns="urn:nhibernate-mapping-2.2">
<class name="CourseDateStudent" table="COURSE_DT_STUD_LNK" lazy="true" >
<composite-id>
<key-many-to-one name="CourseDate">
<column name="COURSE_CODE" />
<column name="COURSE_DT" />
</key-many-to-one>
<key-many-to-one name="Student" column="STUD_ID" />
</composite-id>
<property name="StudentId" insert="false" update="false">
<column name="STUD_ID" sql-type="NUMBER" />
</property>
<property name="CourseCode" insert="false" update="false">
<column name="COURSE_CODE" sql-type="VARCHAR2" not-null="true" />
</property>
<property name="Date" insert="false" update="false">
<column name="COURSE_DT" sql-type="DATETIME" not-null="true" />
</property>
</class>
</hibernate-mapping>
Upvotes: 0
Views: 255
Reputation: 3209
There was a bug in the Breeze code that builds metadata from NHibernate models. As you discovered, it wasn't finding the foreign keys correctly when composite keys were used.
The fix for the issue is now on github and will be in the next release. Sorry it took so long!
Upvotes: 1