2
votes

I'm trying out the automapping capability of Fluent NHibernate, and the same code that worked with explicit ClassMap configurations is failing when building the SessionFactory when I try to move it to automapping.

Here's the code:

public static ISessionFactory GetSessionFactory()
{
    if (_sessionFactory == null)
    {
        _sessionFactory = Fluently.Configure()
            .Database(MsSqlConfiguration.MsSql2008.ConnectionString(c => c.FromConnectionStringWithKey("DB")))
            // It works with the following:
            // .Mappings(m => m.FluentMappings.AddFromAssemblyOf<Customer>())
            // It fails with this:
            .Mappings(m => m.AutoMappings.Add(AutoMap.AssemblyOf<Customer>()))
            .BuildSessionFactory();

    return _sessionFactory;
}

The error I get is:

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

I get Count = 0 for PotentialReasons and the inner exception is the same as above.

The stacktrace refers to:

at FluentNHibernate.Cfg.FluentConfiguration.BuildSessionFactory() in d:\Builds\FluentNH-v1.x-nh3\src\FluentNHibernate\Cfg\FluentConfiguration.cs:line 113

It seems like I've tried everything to get it to work, and the closest I came was to have the initialization work only to get a Could not find persister for... error when I tried to use the session, and I don't even remember how I was able to get that to happen.

I'm using the build #694 with NHibernate 3.0, SQL 2008 database. Any ideas what I'm doing wrong?

1
There are usually 3-4 levels of nested inner exception. Have you examined them all?Aliostad
Wow...I feel like an idiot now! You're absolutely correct - when I drilled down I saw it's an issue mapping enums. In my explicit mappings I just did a CustomType(typeof(MyEnum)) but I'll have to see how that's possible when automapping...Josh Anderson

1 Answers

2
votes

This was a dumb error that Aliostad's comment helped me find. I had an enum type that was stored as an integer in the database, and NHibernate was choking on that. I added an EnumConvention to the setup like this:

_sessionFactory = Fluently.Configure()
    .Database(MsSqlConfiguration.MsSql2008.ConnectionString(c => c.FromConnectionStringWithKey("DB")))
    .Mappings(
        m =>
        m.AutoMappings.Add(AutoMap.AssemblyOf<Customer>(new AutomapConfiguration()).Conventions.
                               Setup(c =>
                                         {
                                             c.Add<PrimaryKeyConvention>();
                                             c.Add<EnumConvention>();
                                             c.Add<CascadeAllConvention>();
                                         })
                               .IgnoreBase(typeof (EntityBase<>))
                               .OverrideAll(map => map.IgnoreProperty("IsValid"))))
    .BuildSessionFactory();

Here's that enum convention:

public class EnumConvention : IUserTypeConvention
{
    public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria)
    {
        criteria.Expect(x => x.Property.PropertyType.IsEnum);
    }

    public void Apply(IPropertyInstance target)
    {
        target.CustomType(target.Property.PropertyType);
    }
}