Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fluently.Configure an NHibernate database from a config file?

This question is similar to Configuring Fluent NHibernate from NHibernate config section but I'm still trying to wrap my brain around this and the answer is not sufficient.

I want to make a database-agnostic inventory management application (more as an experiment than anything else). I want to use the Fluent automapper because it seems like a really cool idea if I could get it to work... keeps things nice and generic and kinda forces you to use a pattern.

So, I make a helper class with a SessionFactory creator like so:

    private static ISessionFactory _SessionFactory;

    public static ISessionFactory SessionFactory {
        get {
            if (_SessionFactory == null) {

                var config = new Configuration().Configure();
                _SessionFactory = Fluently.Configure(config)
                    .Mappings (m => m.AutoMappings.Add (AutoMap.AssemblyOf<Machine> ()))
                    .BuildSessionFactory ();
            }
            return _SessionFactory;
        } 
    }

    public static ISession GetSession()
    {
        return SessionFactory.OpenSession();
    }

I make an app.config like so:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <configSections>
        <section name="hibernate-configuration" type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate" />
    </configSections>
    <connectionStrings>
        <add name="NHDataModel" connectionString="Data Source=10.10.10.10;Integrated Security=SSPI;Database=Inventory;" />
    </connectionStrings>
    <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
        <session-factory>
            <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
            <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
            <property name="dialect">NHibernate.Dialect.MsSql2005Dialect</property>
            <property name="connection.connection_string_name">NHDataModel</property>
            <property name="show_sql">true</property>
        </session-factory>
    </hibernate-configuration>
</configuration>

The error message I get when I try to generate a session to play with is as follows:

An invalid or incomplete configuration was used while creating a SessionFactory. Check PotentialReasons collection, and InnerException for more detail.

  * Database was not configured through Database method.

There is no inner exception.

I would think this works, but I would, of course, be wrong. An examination of the config object shows that it has collected the property information in the app config, yet cannot seem to apply it to the fluent Database Method. I have seen examples very similar to this all over the internet, though none matched exactly, so there's lots of room for stupid mistakes.

I'm sure this is a simple thing, but I've been scratching my head over this for hours. Any help would be greatly appreciated. Nhibernate and FluentNhibernate are techs that I've never used before so this has been a steep learning curve.

like image 345
Jeremy Holovacs Avatar asked Feb 23 '23 15:02

Jeremy Holovacs


1 Answers

Your method seems sound; Fluent NHibernate should indeed allow you to start with a Configuration and add to it. Here's the code from the Fluent NHibernate site, which is semantically identical to yours except you're automapping instead of fluently mapping:

var cfg = new NHibernate.Cfg.Configuration();
cfg.Configure(); // read config default style
Fluently.Configure(cfg)
    .Mappings(
      m => m.FluentMappings.AddFromAssemblyOf<Entity>())
    .BuildSessionFactory();

The only major difference I see is that the site's code never explicitly assigns the config object variable to the results of the Configure() method; this would imply that Configure() modifies the instance on which it's called in addition to returning a deep clone of itself (or just itself).

Some things to check: Are you SURE that the version of Fluent you're using references a version of NHibernate that uses the configuration version 2.2? FNH 1.2 targets NH 3.1, while FNH 1.1 targets NH 2.1.2GA. I do not know which configuration versions either of those use, but if they match the NH version then the Configure() method may not be finding the config section matching the ConfigSectionHandler it's using.

like image 61
KeithS Avatar answered Feb 25 '23 15:02

KeithS