4

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.

Community
  • 1
  • 1
Jeremy Holovacs
  • 22,480
  • 33
  • 117
  • 254

3 Answers3

4

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.

KeithS
  • 70,210
  • 21
  • 112
  • 164
2

I think that Keith is right in that you are not actually populating the NHibernate configuration you have into Fluently.Configure, and thus your configuration is basically ignored. I know you may wish to keep these settings in your configuration file, but if you are willing to bypass the configuration file, you can also do

            _SessionFactory = Fluently.Configure(config)
                .Database(MsSqlConfiguration.MsSql2005.ConnectionString("the connection string"))
                .Mappings (m => m.AutoMappings.Add (AutoMap.AssemblyOf<Machine> ()))
                .BuildSessionFactory ();

If you do that, you no longer need <hibernate-configuration> in your configuration file, and it should fix your problem.

Mike Richards
  • 5,557
  • 3
  • 28
  • 34
  • 1
    Yeah I'm trying to avoid that. I really want to see a database-agnostic version of NH. – Jeremy Holovacs Oct 20 '11 at 23:39
  • 1
    Sure, I can understand that from a practice exercise standpoint. Keep in mind that in most circumstances though, if you did need to change the entire application from one type of database to another, then you probably don't care about recompiling the dll. If that circumstance did come up, like let's say you're upgrading to Sql Server 2008, then you just need to change `MsSqlConfiguration.MsSql2005` to `MsSqlConfiguration.MsSql2008`. The platform is still database-agnostic. – Mike Richards Oct 21 '11 at 01:41
  • @MikeRichards, we support multiple databases and activate Oracle vs SQL server depending on target installation – Maulik Modi Jan 27 '21 at 16:41
2

Well thanks for the sanity check. It turns out that the problem had to do with the automapping configuration, nothing to do with the database at all. The error message was throwing me and causing me to look in the wrong place. I think I will make a note on the Fluent forum that the wrong message is popping up in that scenario, so that other people don't end up spinning their wheels on this.

Jeremy Holovacs
  • 22,480
  • 33
  • 117
  • 254
  • What specifically was causing the problem? It might help other people figure out their problem in the future if you post the details here. – Daniel Schilling Oct 21 '11 at 18:43
  • 1
    It could not infer the Id column (I was using ID instead of Id)... once I told it what to look for, the error went away. – Jeremy Holovacs Oct 21 '11 at 18:55