Saturday, March 22, 2014

S#arp Architecure, Multiple Database and Class Maps

Recently, I've been updated a ASP.NET MVC project which is based on the S#arp Architecture.  I needed to extend the existing function to talk to a second database.

In order to do this, I followed the S#arp Architecture guide to multiple databases which can be found here. This shows you how to add a second NHibernate configuration to your project and how to apply an attribute to your repository so it knows that which NHibernate configuration to use. This seemed to be perfect as out of the box, NHibernate didn't seem to have the facility to support multiple database sessions - well at least not easily.

So following the guide, I integrated the changes into the existing software - unfortunately this didn't work.

The issue was that I had the POCO classes and NHibernate Class Maps for both databases in the one assembly NHibernate would attempt to apply the class maps and POCO classes to only one database Session - causing NHibernate to throw "No Persister Found" errors and similar errors. As I didn't like the idea of splitting the project up into two assemblies for the sake of it (one for each database), I went looking for alternatives.

To fix the POCO issue was easy,  I just created an empty interface representing each database and applied that interface to each of the POCO objects accordingly, then in AutoPersistenceModelGenerator I simply had two different versions of the Generate method for each database which I used when settings up my Sessions in the calls to NHibernateSession.Init() and NHibernateSession.AddConfiguration().

The Class maps were not so easy, after doing a lot of research and finding that ClassMaps can't be filtered out in the Same way as POCO objects, I was very much stuck until I found this blog post.  Although this blog post had nothing to do with multiple databases, it did point out that in the S#arp Architecture you should not use ClassMaps, but instead use Overrides that are provided by the S#arp Architecture.

In the S#arp Architecture when using AutoMapping, Overrides represent those classes which shouldn't be AutoMapped on conventions and instead have custom mappings that don't match the convention.  The Overrides are basically the same ClassMaps and also use the same syntax.

To my surprise after converting the ClassMaps to Overrides (which only took a few minutes), it seems that S#arp Architecture could then work out which Override (i.e. Map) applied to which database and applied the where they were appropriate - no more errors.  And because there were no long any Class Maps, NHibernate wasn't trying to automatically assume that all ClassMaps belonged to the current Session that was being initialized.

Anyhow, thought I would document this in case someone else is facing the same situation.

:)