Tigraine

Daniel Hoelbling-Inzko talks about programming

Fluent NHibernate gotchas when testing with an in memory database.

Posted by Daniel Hölbling on May 29, 2009

What I love most about programmatic configuration is that it’s close to the test.
While we were carrying dozens of XML files around for testing before, now with DSL based configuration everywhere the configuration is usually pretty near to the test fixture, instead of residing in some arbitrary XML that only insiders can associate with the test.

The standard sample for using SqlLite and Fluent NHibernate usually looks like this:

return
    Fluently
        .Configure()
        .Database(SQLiteConfiguration.Standard.UsingFile("mydb.db3").ShowSql())
        .Mappings(m => m.FluentMappings.AddFromAssemblyOf<SessionFactory>())
        .ExposeConfiguration(SaveSchema)
        .BuildSessionFactory();

Where SaveSchema is a method that does a database rebuild.

Now, Fluent Nhibernate has in-memory databases built into the API. Just remove the UsingFile directive and you replace it with:

.Database(SQLiteConfiguration.Standard.InMemory().ShowSql())

Charming isn’t it? Now the only problem is that you won’t be able to do anything with that DB since there is no schema present.
The in-memory database exists per session, so once you close the ISession the db is gone. Since the schema export from most samples operates in it’s own ISession the subsequent queries will still hit a blank database, and you’ll get an error stating there is no such table.

So my SessionFactory implementation had to change, since I needed to keep the configuration around for doing the schema export:

public class SessionFactory
{
    public static ISessionFactory CreateSessionFactory()
    {
        return
            Fluently
                .Configure()
                .Database(SQLiteConfiguration.Standard.InMemory().ShowSql())
                .Mappings(m => m.FluentMappings.AddFromAssemblyOf<SessionFactory>())
                .ExposeConfiguration((c) =>  SavedConfig = c)
                .BuildSessionFactory();
    }

    private static Configuration SavedConfig;

    public static void BuildSchema(ISession session)     {         var export = new SchemaExport(SavedConfig);         export.Execute(true, true, false, false, session.Connection, null);     } }

And my tests then use a another factory method to construct the ISession object:

public static ISession CreateSession()
{
    var factory = SessionFactory.CreateSessionFactory();
    var session = factory.OpenSession();
    SessionFactory.BuildSchema(session);

    return session; }

Hope this helps, quite an annoying problem and imo a far from perfect solution. Someone on the FNH mailing list suggested looking at the OneToManyIntegrationTester class but I couldn’t really extract any terribly useful information from there.

Filed under net, programmierung, nhibernate
comments powered by Disqus

My Photography business

Projects

dynamic css for .NET

Archives

more