Unless you live under a rock or really really really enjoy hand-writing every SQL query you make, chances are you’ve come across an ORM that maps your domain model to a data storage mechanism. For Lunchage we’re opting to use NHibernate mostly out of familiarity, but also to try out the new “auto-mapping” functionality that eliminates the need for .hbm files or a third-party utility like Fluent NHibernate. If you need a primer for using NHibernate check out their getting started guide or Ayende’s recommended learning material.
Given the domain we’ve created in the last post, I’ve got to wrap the base amount of information I want stored in the database we’re using that will be familiar across all objects. The base “Entity” object will contain Id, Version, CreateDate and LastModified properties in order to place nice with our ORM. The Id, CreateDate and LastModified should be obvious, the Version is a field we will use to manage concurrency issues. My next move is to define how NHibernate maps our domain to the database. As I briefly mentioned above, the newest version of NHibernate (3.2) integrated convention and configuration based mappings that rely on strongly-typed code instead of xml for transforms. Unfortunately this is a relatively new feature and finding documentation on best practices can be difficult. Most of what I’ve done can be referenced through Fabio Maulo’s 3.2 series of articles. To leverage this convention based power, I can define a class for our default mapping configurations.
Pretty simple eh? This configuration should take care of 80% of what we need out of our ORM. You’ll notice there is one reference to an explicit map around line 39, that’s because we’re defining a ManyToMany for Restaurants to Tags but don’t really care or have the domain Tag class knowing about our restaurants. Otherwise, we could probably map a convention for ManyToMany and be done with the whole process.
Once configuration is done, I write a test to create and export the schema which should verify that our domain matches the database and will detect whenever we’ve mapped something improperly.
Before this test can run, I have to define the configuration for NHibernate and this is vastly different (re: way simpler) to do than previous incarnations. Again, though, there isn’t a ton of documentation at this time on getting configuration up and running. Instead of configuration individual variables on the configuration object, we interact we an object called DatabaseIntegration on the Configuration to specify the db dialect and connection string. The final step is to add the mapping files to the configuration and, BOOM, we’re ready to go. You can still specify configuration parameters via Configuration.SetProperty(Key,Value) by why would you when half of the work is already done? (Note though, we’ll likely need to make some changes once we get into a web environment).
That’s that. We have enough to generate our database and have our system not die. Also at the bottom notice I’ve created a function to export our xml mapping files should we feel the need to confirm any mapping issues. If anyone out there knows a native way of doing this in NHibernate 3.2 please do tell. We’ve made our UI decisions so we’ll now start scaffolding up the site’s layout and UI interaction in order to get some of the back-end work come together.