# Thursday, November 01, 2007

I downloaded the NHibernate VS2005 plugin and started to use it - its very similar to the Hibernate support built into Eclipse.  Unfortunately after playing around with it for about 20 minutes I realized my data model (in the DB) was complete poo and the plugin wasn't built to handle legacy databases, which I completely understand because that's where the majority of NHibernate's complexity lies IMO.

I really don't want the crappy data model to leak into my object model - even though it would be super easy and fast to "whip it out" using the plugin or another code generator.  I'm kind of stuck on what to do right now.  Part of the problem is I'm not sure I have time to "do it right." I have a hard deadline looming from a 3rd party that can't budge.


I think I may start out modeling my object model from scratch, which isn't too bad with Re# installed.  Then from there start manually mapping some of this stuff to the existing sprocs or creating some new views.  I also have the problem that this will all be serialized and sent over a web service and/or NServiceBus, so I'm not sure how to handle relationships.  Probably in most cases I'll just have IDs of the FKs and then explicitly make another fetch from the service since lazy loading is pretty much out of the question.

Thursday, November 01, 2007 3:17:34 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, May 18, 2007
I moved my little demo application (aka FoodBankTracker) that I use for demoing tech over to Visual Studio 2007 / .NET 3.5 today without much hassle.  The only real hassle I had was with log4net version/strong key mismatches between MonoRail RC2 and NHibernate 1.2 GA, but that's entirely another story.  The main reason I wanted to move it over to the new platform was to really try out the new language integrated queries (LINQ).  I ended up using the LINQ -> NHibernate criteria adapter being maintained by Ayende for several reasons:
  1. My NHibernate mapping files are complete.
  2. I like the unit of work NHibernate provides.
  3. Its always good to have some abstraction between the domain and the database layer.
  4. I'm familiar with NHibernate and already have infrastructure in place for it.
I grabbed the latest code from subversion for the LINQ -> NHibernate adapter and was up and running in no time.  The only change I had to make was to upgrade the NHibernate version from 1.2 beta3 to 1.2GA.  The hardest part was figuring out that I needed to add an assembly reference to System.Core for .NET 3.5 in my project.  Anyway, here's the one test I have working with LINQ and for comparison I'm also showing the original test without LINQ which does the same thing.

Friday, May 18, 2007 6:56:17 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, April 24, 2007
I was going to use the NHibernate facility provided by Castle Windsor until I found out it didn't support using class mapping attributes.  I ended up rolling my own implementation but added a couple new features to my implementation:

  • Automatic context aware session container (web context or thread local).
  • Ability to use NHibernate mapping attributes instead of hbm.xml files.
  • Can use the built-in .NET 2.0 connectionStrings element to specify an NHibernate connection string.
I think the first two items are pretty obvious, but the last feature I added because most standard .NET applications make use of these elements - for better or worse.  I think its a good idea to be consistent if possible.  Additionally this would allow any standard .NET administration tool to examine and edit the connection string for the application.

I also wanted the ability to use a custom configuration section so that I could add additional elements and attributes as needed.  The configuration section handler produces a SessionFactoryConfiguration instance, which itself it a subclass of NHibernate.Cfg.Configuration.  The configuration section looks like this:

  <sessionManager>
    <settings>
      <setting name="hibernate.dialect">NHibernate.Dialect.MsSql2000Dialect</setting>
      <setting name="hibernate.connection.driver_class">NHibernate.Driver.SqlClientDriver</setting>
      <setting name="dotnet.connection_string">Laptop</setting>
      <setting name="hibernate.connection.provider">
         NHibernate.Connection.DriverConnectionProvider
      </setting>
    </settings>
    <resources>
      <resource assembly="Sneal.Northwind.Core" useAttributes="true"/>
    </resources>
  </sessionManager>

Notice the setting dotnet.connection_string.  This is the custom hook I added to my custom configuration handler that resolves Laptop to the .NET connection string named Laptop:

  <connectionStrings>
    <add name="Laptop" connectionString="Database=Northwind; Data Source=.\sqldev2000;" />
  </connectionStrings>

Then I just wire up my SessionManager instance to my Repository instance using an IoC container; currently Windsor.  I have an HttpModule which handles my Unit of Work currently, but unfortunately its tied to Windsor and my current application, so now I'm off to decouple it for reuse.
 

Tuesday, April 24, 2007 5:26:12 AM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, December 06, 2006
A Hibernate session is a "unit of work."  Useful resource for understanding unit of work and transactions within Hibernate: http://www.hibernate.org/42.html

Wednesday, December 06, 2006 10:47:46 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, November 28, 2006

See comments...

/**
* Iterates through all mapped Hibernate classes and attempts to select
* all for that table/class pair. If this test does not fail then this
* indicates that the hibernate mappings at the very minimum match the
* database schema.
*/

@Test
public void allHibernateMappingsWork()
{
    Configuration configuration = new Configuration();
    configuration.setProperty(Environment.SHOW_SQL, "true");
    
    SessionFactory sessionFactory = configuration.configure().buildSessionFactory();
    Session session = sessionFactory.openSession();
    
    Map metaData = sessionFactory.getAllClassMetadata();
    for (Iterator i = metaData.values().iterator(); i.hasNext();)
    {
        EntityPersister persister = (EntityPersister) i.next();
        String className = persister.getClassMetadata().getEntityName();
        String qry = "from " + className + " c";
        List result = session.createQuery(qry).list();
        assertTrue("No results for " + className, result.size() > 0);
    }
    
    session.close();
}

Tuesday, November 28, 2006 9:37:44 PM (GMT Standard Time, UTC+00:00)  #    Disclaimer  |  Comments [0]  |