Like many things in NHibernate, causes of the PropertyAccessException aren’t particularly well documented. (Well, they may be documented somewhere, but dang if I can find much on it.) My NUnit tests were throwing this error during relationship tests with the “amplifying” message that the properties I was using for ID values weren’t the correct type.
Huh? Single entity stores were working just ducky, but trying to work with many-to-many relationships was failing. The many-to-many definitions in the hbm.xml map files were all fine — trust me, I double-checked them about eight million times last night between 11pm and 1am when I finally quit last night.
This morning I finally found a Google hit that pointed me in the right direction: incorrect storage of the referenced entity, causing a null value in a member of type “Int32”. You have to be sure you correctly set your collection properties in both sides of a relationship you’re trying to store via NHibernate. It turns out I was incorrectly setting a collection on one side of my relationship.
Here’s the working (but not optimized) code:
[
Test]public void CheckAddPersonWithOneType(){
PersonEntity personToDB = tep.MakeDefaultPersonEntity();//Add the Person to the PersonType object's collection
speakerType.Persons.Add(personToDB);
//Add the PersonType to the Person object's collectionpersonToDB.PersonTypes.Add(speakerType);
IDal<PersonEntity> pda = new PersonDA();int storedID = (int)pda.AddEntity(personToDB);PersonEntity fromDB = pda.GetEntity(storedID);IList retTypes = new ArrayList(fromDB.PersonTypes);foreach (PersonTypeEntity type in personToDB.PersonTypes){
Assert.IsTrue(retTypes.Contains(type));
}
//clean up listspeakerType.Persons.Remove(personToDB);
}
The all important lines are here://Add the Person to the PersonType object's collection
speakerType.Persons.Add(personToDB);
//Add the PersonType to the Person object's collectionpersonToDB.PersonTypes.Add(speakerType);
speakerType is one end of the relationship, persontoDB is the other. Persons and PersonTypes are the collections holding the other end of the relationship.
Remeber that this is a many-to-many relationship? Remember that m-m relationships need a link table between the two entities? What’s cool about NHibernate is that I don’t have to fool at all with storing stuff in that link table. NHibernate handles all that for me when I store the entities with one statement:
storedID = (int)pda.AddEntity(personToDB);int
Way cool.
NHibernate’s learning curve (and #%*@!! documentation) is tough going, but I think I’m going to like things once I get up to the next plateau. I’m also weary of trying to wade through examples which aren’t much help. Hopefully I’ll be able to put up some clear examples once I get things working well and refactored for clarity.
Now Playing: Guster — Lost and Gone Forever. I’ve been playing a lot of Guster and Coldplay lately. Well, a lot of other stuff, too, plus Springsteen’s The Rising seems to be stuck in my audio stream for some reason. In any case, I really dig the cool harmonies and melodies. Plus the lyrics are pretty thoughtful. (Unlike The Mavericks, who I love but seem to be of the Gene Autry school of All My Songs Have Five Words.)
No comments:
Post a Comment