NHibernate - Override Configuration



In this chapter, we will be covering how to override NHibernate configuration. There are just a few things you need to keep in mind.

  • First of all, configuration in NHibernate is additive.

  • So you don't just have to use a single xml file or you don't just have to use the code-based configuration or fluent NHibernate.

  • You can mix and match all of these methods depending on how you want to configure your application.

  • The important point to remember is that, lastly configuration wins.

In the following example, you can see that we create our configuration object, configure it using the code-based configuration and finally call the cfg.configure() method, which loads the hibernate.cfg.xml file.

String Data Source = asia13797\\sqlexpress; String Initial Catalog = NHibernateDemoDB; String Integrated Security = True; String Connect Timeout = 15; String Encrypt = False; String TrustServerCertificate = False; String ApplicationIntent = ReadWrite; String MultiSubnetFailover = False; cfg.DataBaseIntegration(x = > { x.ConnectionString = "Data Source + Initial Catalog + Integrated Security + Connect Timeout + Encrypt + TrustServerCertificate + ApplicationIntent + MultiSubnetFailover"; x.Driver<SqlClientDriver>(); x.Dialect<MsSql2008Dialect>(); x.LogSqlInConsole = true; }); cfg.Configure();
  • So anything inside of a hibernate.cfg.xml overrides the settings set by code-based configuration.

  • By reversing these two processes we can have the defaults inside of hibernate.cfg.xml and then do our overrides inside of a code-based configuration.

  • There is nothing that excludes if you are using code-based configuration and also there is nothing that prevents you from using the hibernate.cfg.xml file.

Lets have a look into a simple example in which we will override the configuration by using a mixture of xml-based and code-based configuration.

Lets also move the connection string to the app.config file using the following code.

<?xml version = "1.0" encoding = "utf-8" ?> <configuration> <startup> <supportedRuntime version = "v4.0" sku = ".NETFramework,Version = v4.5" /> </startup> <connectionStrings> <add name = "default" connectionString = "Data Source = asia13797\\sqlexpress; Initial Catalog = NHibernateDemoDB; Integrated Security = True; Connect Timeout = 15; Encrypt = False; TrustServerCertificate = False; ApplicationIntent = ReadWrite; MultiSubnetFailover = False"/> </connectionStrings> </configuration>

The connection string is sitting in some app.config file with a default name. Now, we need to mention the default name in hibernate.cfg.xml file instead of the connection string.

<?xml version = "1.0" encoding = "utf-8" ?> <hibernate-configuration xmlns = "urn:nhibernate-configuration-2.2"> <session-factory> <property name = "connection.connection_string">default</property> <property name = "connection.driver_class"> NHibernate.Driver.SqlClientDriver </property> <property name = "dialect"> NHibernate.Dialect.MsSql2008Dialect </property> <mapping assembly = "NHibernateDemoApp"/> </session-factory> </hibernate-configuration>

Lets comment on the connection string part, driver, and dialect part from the code-based configuration, because the program will read it from the hibernate.cfg.xml file and the LogSqlInConsole part will remain in the code-based configuration.

using HibernatingRhinos.Profiler.Appender.NHibernate; using NHibernate.Cfg; using NHibernate.Dialect; using NHibernate.Driver; using System; using System.Linq; using System.Reflection; namespace NHibernateDemoApp { class Program { static void Main(string[] args) { NHibernateProfiler.Initialize(); var cfg = new Configuration(); String Data Source = asia13797\\sqlexpress; String Initial Catalog = NHibernateDemoDB; String Integrated Security = True; String Connect Timeout = 15; String Encrypt = False; String TrustServerCertificate = False; String ApplicationIntent = ReadWrite; String MultiSubnetFailover = False; cfg.DataBaseIntegration(x = > { //x.ConnectionString = "Data Source + Initial Catalog + Integrated Security + Connect Timeout + Encrypt + TrustServerCertificate + ApplicationIntent + MultiSubnetFailover"; //x.Driver<SqlClientDriver>(); //x.Dialect<MsSql2008Dialect>(); x.LogSqlInConsole = true; }); cfg.Configure(); cfg.AddAssembly(Assembly.GetExecutingAssembly()); var sefact = cfg.BuildSessionFactory(); using (var session = sefact.OpenSession()) { using (var tx = session.BeginTransaction()) { var students = session.CreateCriteria<Student>().List<Student>(); Console.WriteLine("\nFetch the complete list again\n"); foreach (var student in students) { Console.WriteLine("{0} \t{1} \t{2} \t{3}", student.ID, student.FirstName, student.LastName, student.AcademicStanding); } tx.Commit(); } Console.ReadLine(); } } } }

Now when you run the application, you will see that the program has read the log from code-based configuration and other configuration from the hibernate.cfg.xml file.

NHibernate: SELECT this_.ID as ID0_0_, this_.LastName as LastName0_0_,   
   this_.FirstMidName as FirstMid3_0_0_, this_.AcademicStanding as Academic4_0_0_ FROM
   Student this_

Fetch the complete list again
1 Allan Bommer Excellent
2 Jerry Lewis Good

So now we have got some of our configuration inside of our hibernate.cfg.xml file, some of it is inside of the code-based configuration and depending on the order of calling code-based versus configure(), we can change which of them overrides the other.

Advertisements