After a good few months in hibernation the guilt of leaving my poor pet project half-finished has finally got to me!
I was also spurred on by several new (and not so new) software releases that I would like to try out:
The first step I needed to take was to upgrade the project to use the new release of Sharp Architecture and MVC 2. The Sharp Architecture wiki has a decent upgrade guide and I was able to get most of the way there by following this. However there were a couple extra step I needed to take in my project:
Upgrade to Fluent NHibernate
I think my project may have been on an earlier version than that in the guide because I needed to upgrade the Data project to use Fluent NHibernate. The issues here were pretty obvious as there were several compilation errors. I found the easiest solution was to generate a new empty Sharp Architecture project from the 1.6 template, then copy across the amended files in the NHibernateMaps folder.
This got the application to compile OK, however there were a couple of differences in the configuration from my project.
Primary Key Convention
One of the data unit tests was failing when trying to access an entity using the .Get(id) method. This was strange as the entity was being loaded OK in the setup method. I was also getting an exception from the website when trying to add an entity to the database:
Invalid object name ‘hibernate_unique_key’.
The problem was due to a change in the PrimaryKeyConvention class. The convention for generating primary keys has been changed from Native() to HiLo(“1000″). So instead of the first record having a key of 0 it would now try to use 1000. Changing this setting back to Native() fixed the problem straight away.
The other issue I encountered occurred when trying to add a new ingredient to a recipe:
Cannot insert the value NULL into column ‘IngredientFk’, table ‘recipebook.dbo.RecipeIngredientDrafts’; column does not allow nulls. INSERT fails.
The statement has been terminated.
This error pointed to a problem with NHibernate not saving changes to associated entities; it was trying to save a new RecipeIngredientDraft record without first saving the new Ingredient record. This issue could be resolved by adding a call to instance.Cascade.SaveUpdate() in the ReferenceConvention and HasManyConvention classes.
After fixing these issues the application worked just fine