Свободный экспорт NHibernate (1.2.0.712) в HBM не работает / не соблюдает соглашения

Функция экспорта HBM в Fluent NHibernate, похоже, не работает.

Если я вызываю FluentMappingsContainer.ExportTo, сгенерированные сопоставления получаются неверными, и я получаю следующее исключение:

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

Мой код конфигурации выглядит так:

        MsSqlConfiguration database = MsSqlConfiguration.MsSql2008
            .ConnectionString(GetConnectionString())
            .Cache(c => c
                            .UseQueryCache()
                            .UseSecondLevelCache()
                            .ProviderClass<SysCacheProvider>()
            );

        database.ShowSql();

        FluentConfiguration config = Fluently.Configure()
            .Database(database)
            .Mappings(m => m.FluentMappings.AddFromAssemblyOf<Entity>()
                               .Conventions.AddFromAssemblyOf<Entity>());

        config.ExposeConfiguration(x =>
        {
            x.SetProperty("hbm2ddl.keywords", "auto-quote");
            x.SetInterceptor(new ServiceInterceptor());
        });

        config.ExposeConfiguration(x => { x.SetProperty("current_session_context_class", "thread_static"); });

        // Configure HBM export path, if configured:

        var path = Service.Config.HbmExportPath;

        if (!String.IsNullOrEmpty(path))
            config.Mappings(m => m.FluentMappings.ExportTo(path));

        // Build session factory:

        _sessionFactory = config.BuildSessionFactory();

Если в моей конфигурации HbmExportPath указано значение null, приложение запускается и работает без проблем. Как только я настраиваю путь экспорта (вызывая ExportTo), сгенерированные отображения вызывают исключение, как описано выше.

Глядя на экспортированные отображения, кажется, что мои соглашения не применяются - например, у меня есть соглашение о внешнем ключе, использующее регистр верблюда и суффикс "Id", но когда я экспортирую файлы HBM, первичные ключи согласованно именуется символом подчеркивания и нижнего регистра "_id", например:

<class xmlns="urn:nhibernate-mapping-2.2" name="MyApp.Entities.Contact, MyApp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null" table="`Contact`">
  ...
  <bag name="Departments" table="ContactDepartment">
    <key>
      <column name="Contact_id" />
    </key>
    <many-to-many class="MyApp.Entities.Department, MyApp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
      <column name="Department_id" />
    </many-to-many>
  </bag>
  ...
</class>

У меня была эта проблема с предыдущей версией и с текущей версией Fluent.

Есть идеи?

1 ответ

Решение

После детализации исходного кода Fluent (последний из репозитория Git) мне что-то показалось странным.

Методы ExportTo() определяются дважды - один раз самим FluentConfiguration, и кажется, что он экспортирует файлы конфигурации "слишком рано", что приводит к неполной конфигурации, как во время выполнения (что приводит к приведенному выше исключению), так и при экспорте время.

Как ни странно, тип PersistenceModel имеет возможность экспортировать полную конфигурацию, но эта функция не предоставляется. Вместо этого есть как минимум две другие, казалось бы, неработающие реализации ExportTo().

Чтобы решить эту проблему, нам нужен доступ к экземпляру PersistenceModel, который имеет возможность написать полную конфигурацию - к счастью, я нашел способ сделать это:

        // create a local instance of the PersistenceModel type:
        PersistenceModel model = new PersistenceModel();

        FluentConfiguration config = Fluently.Configure()
            .Database(database)
            .Mappings(m => m.UsePersistenceModel(model) // use the local instance!
                               .FluentMappings.AddFromAssemblyOf<Entity>()
                               .Conventions.AddFromAssemblyOf<Entity>());

        // ...

        var path = Service.Config.HbmExportPath;

        _sessionFactory = config.BuildSessionFactory(); // completes the configuration

        // now write out the full mappings from the PersistenceModel:

        if (!String.IsNullOrEmpty(path))
            model.WriteMappingsTo(path);

Файлы HBM теперь выводятся правильно!

Другие вопросы по тегам