5

I've seen the various blog posts concerning nHibernate's SchemaUpdate, and even Ayende's very good example, and downloaded the samples, but for some reason I cannot get the same same thing to work for me. I will note that I am using Fluent NHibernate, but from what I can tell that should not make too huge a difference.

Update

I have reached the point where the SchemaUpdate runs, but it is just a full schema creation, no 'altering'. In otherwords, it's the same as if I just built the database fresh. I am posting my full source below.

Here Is what I am basically trying... I think it is generally self obvious, but basically I am creating a Configuration object using the Fluent Configuration, and then trying to pass it in. Unit Tests pass, programs run ...but nothing actually happens. I can never see any results, and I can never see the database schema get updated.

Database gets created (missing columns, etc)

Database then gets mapped with new schema on next run.

Database (Update) should update the Schema per the Update method.

But that isn't what is actually happening.

I also looked at other posts on the matter. Like here : http://morten.lyhr.dk/2008/03/nhibernates-schemaupdate-feature.html

Additionally, I have changed my code after finding the following Stack Overflow post Make Fluent NHibernate output schema update to file

And even with the sample code was not able to make heads or tails of this feature.

Code

    private static void UpdateSchema(NHibernate.Cfg.Configuration Config) {
        System.Action<string> updateExport = x => {
            using (var file = new System.IO.FileStream(@"C:\Users\User\Documents\Visual Studio 2010\Mappings\update.sql", System.IO.FileMode.Append, System.IO.FileAccess.Write))
            using (var sw = new System.IO.StreamWriter(file)) {
                sw.Write(x);
                sw.Close();
            }
        };
        NHibernate.Tool.hbm2ddl.SchemaUpdate SchemaUpdater = new NHibernate.Tool.hbm2ddl.SchemaUpdate(Config);
        SchemaUpdater.Execute(updateExport, false);
    }
    
    public static ISessionFactory Map(string connectionString) {
        // fluently configure an ms-sql 2008 database
        return FluentNHibernate.Cfg.Fluently.Configure()
            .Database(FluentNHibernate.Cfg.Db.MsSqlConfiguration.MsSql2008
                      .ConnectionString(c => c.Is(connectionString))
                      .AdoNetBatchSize(50)
                      .FormatSql()
                      .UseReflectionOptimizer())
            .Cache(c => c
                   .ProviderClass<NHibernate.Caches.SysCache2.SysCacheProvider>()
                   .UseQueryCache()
                   .UseSecondLevelCache()
                   .UseMinimalPuts())
            .Mappings(m => {
                m.FluentMappings.Conventions.Setup(x => {
                        x.AddFromAssemblyOf<Mappings.AspectMap>();
                        x.Add<EnumConvention>();
                        x.Add(FluentNHibernate.Conventions.Helpers.AutoImport.Never());
                    });
                m.FluentMappings.AddFromAssembly(System.Reflection.Assembly.GetExecutingAssembly());
            })
            .ExposeConfiguration(UpdateSchema)
            .BuildSessionFactory();
    }
Community
  • 1
  • 1
Ciel
  • 17,312
  • 21
  • 104
  • 199
  • Ceil, I haven't tried SchemaUpdate with Fluent NHibernate, but with mapping files, the .hbm file is embedded as a resource into your DataLayer.dll. The update compares the current schema to the intended schema and adds anything that's missing. – Eric Farr Jul 16 '11 at 14:59
  • are you willing to try any other approach for upgrading your schema or do you want to stick to schemaupdate – Baz1nga Jul 16 '11 at 17:17
  • I am willing to try a different approach. – Ciel Jul 16 '11 at 17:40
  • What if there is no "DataLayer.dll"? – Ciel Jul 16 '11 at 18:07
  • 1
    The AddAssembly call just needs to reference where the mapping is embedded. It could be the currently executing assembly. – Eric Farr Jul 16 '11 at 20:02

1 Answers1

4

Your example works well for me (NH3.1, FNH 2.1). SchemaUpdater checks current database schema and creates correct alter scripts. All generated script fragments are exposed to UpdateSchema. No problem here. The only one detail which I was confused by is file mode access:

  1. First Map run: Whole database schema script is stored in update.sql file. Note that there the script is not executed yet, because doUpdate parameter is false: SchemaUpdater.Execute(updateExport, false);
  2. Execute update.sql file manually - database schema is created.
  3. Change in FNH mapping (e.g. a property is added).
  4. Second Map run: Corretct alter table script is appended to update.sql file.

Maybe it would be better to remove the output file before schema update.

The generated script can be executed automatically (doUpdate parameter is true):

SchemaUpdater.Execute(updateExport, true);

I don't know if it is your case but I'm happy now - your code snippet solved some of my problems. Thanks for inspiration:).

Jakub Linhart
  • 4,062
  • 1
  • 26
  • 42
  • Ok. My problem was that I was not running it a second time. Apparently you cannot do a Schema Update on the first run, you have to do it on the second. – Ciel Jul 26 '11 at 09:55