Take the 2-minute tour ×

I'm using NHibernate to connect to an ERP database on our DB2 server. We have a test schema and a production schema. Both schemas have the same table structure underneath. For testing, I would like to use the same mapping classes but point NHibernate to the test environment when needed and then back when in production. Please keep in mind that we have many production schemas and each production schema has an equivalent test schema.

I know that my XML mapping file has a schema property inside it, but since it's in XML, it's not like I can change it via a compiler directive or change the schema property based on a config file.

Any ideas?

Thank You.

share|improve this question
add comment

5 Answers

No need to specify schema in the mappings: there's a SessionFactory-level setting called default_schema. However, you can't change it at runtime, as NHibernate pregenerates and/or caches SQL queries, including the schema part.

share|improve this answer
exactly, so the solution is: build another session factory. –  Mauricio Scheffer Oct 29 '09 at 22:59
ahh, good point Mauricio –  zvolkov Oct 29 '09 at 23:53
Thanks for the reply. Based on your info, I don't think I have a choice but to keep the schema info inside the mapping file and change it when I'm done with testing. I have at least two production schemas so setting a default schema in the factory would require a factory for every schema, or having the schema property set for some mappings but not others. I've read that factories are heavy and to avoid more than one so I think I'm left with changing just the schema properties in the mapping files. I wish I could create a mapping interface and override just the property instead. Thanks Again. –  Brian Oct 30 '09 at 12:42
Factories are expensive to create at run time, but not so expensive to keep around. I don't understand how you plan on changing mappings at run time (as alternative to just using the other factory) –  zvolkov Oct 30 '09 at 13:08
I was giving up on the idea of changing the schemas at run-time and instead thought that I would just declare the schema in the mapping file. Is that feasible? Per your suggestion, if I have two different factories based on two different schemas, can I still do a join between two tables from the different schemas or have a master/detail relationship? –  Brian Oct 30 '09 at 13:41
show 1 more comment
up vote 0 down vote accepted

To get what I wanted, I had to use NHibernate.Mapping.Attributes.

[NHibernate.Mapping.Attributes.Class(0, Table = “MyTable”, Schema = MySchemaConfiguration.MySchema)]

In this way, I can create a class like MySchemaConfiguration and have a property inside of it like MySchema. I can either set the property's value via a compiler directive or get it through a configuration file. This way I only have to change the schema in one place and it will be reflected throughout all of the other mappings.

share|improve this answer
add comment

I have found following link that actually fixes the problem.

How to set database schema for namespace in nhibernate

The sample code could be

cfg.ClassMappings.Where(cm => cm.Table.Schema == "SchemaName")
    .ForEach(cm => cm.Table.Schema = "AnotherSchemaName");

This should happen before you initialize your own data service class.

@Brian, I tried NHibernate.Mapping.Attributes, the attribute value you put inside should be a constant. So it could not be updated during run time. How could you have set the property's value using a parameter value in configuration file?

share|improve this answer
It seems changing the schema in ClassMappings object won't update the schema of all the many-to-many tables. Finally I fixed this problem by update the text value in the resource file extracted from the mapping xml dll. –  Sheng Apr 10 '13 at 22:33
add comment

The code to fix HBM XML resources.

    // This is how you get all the hbm resource names.
    private static IList<string> GetAllHbmXmlResourceNames(Assembly assembly)
        var result = new List<string>();

        foreach (var resource in assembly.GetManifestResourceNames())
            if (resource.EndsWith(".hbm.xml"))

        return result;
    // This is how you get the stream for each resource.
    // What you need to do next is to fix schema name in this stream
    // Replacing schema name.
    private Stream FixSchemaNameInStream(Stream stream)
        StreamReader strStream = new StreamReader(stream);
        string strCfg = strStream.ReadToEnd();
        strCfg = strCfg.Replace(string.Format("schema=\"{0}\"" , originalSchemaName), string.Format("schema=\"{0}\"" , newSchemaName));

        return new MemoryStream(Encoding.ASCII.GetBytes(strCfg));
share|improve this answer
add comment

Take a look at SchemaUpdate.


share|improve this answer
err I suppose that's not exactly what he meant :) –  zvolkov Oct 30 '09 at 1:25
could have helped, ya never know :) –  zowens Oct 30 '09 at 3:10
add comment

Your Answer


