Search code examples
nhibernate.net-4.0executionengineexception

Nhibernate 2.1 with Spring on .net 4 throws System.ExecutionEngineException


I've got a website that works on .Net 3.5 running Nhibernate 2.1.0.4000. We are using spring as our ProxyFactory.

Everything works fine. I have tried to upgrade the project to .Net 4.0 using the wizard. It all went smoothly.

But as soon as the code tries to do anything with Nhibernate I get a very unfriendly exception of System.ExecutionEngineException. There is no stack trace and no inner exception.

We are using a NhibernateHelper class (below) and I've played around with it and the Session gets configured ok (no exception). The details havn't changed any from teh .net 3.5 version

The fist attempt to get something from the DB fails

The session is opened in the handler at the start of the request (not shown below). We are also using unity which is setup on Appliation start (not sure if that has any bearing)

The First call to Nhibernate is

var emp = NHibernateHelper.CurrentSession.Get<SMS.DomainModel.Employee>(-200694);

I just want an error message that means something and gives me something to go on.

I've tried looking at NhibernateProfiler and all that is registered is the start of a session.

Any help is much appreciated

NhibernateHelper Class is as follows

using System;
using System.Configuration;
using System.IO;
using System.Reflection;
using FluentNHibernate;
using FluentNHibernate.Cfg;
using HibernatingRhinos.NHibernate.Profiler.Appender;
using log4net;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Data.Configuration;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Event;
using NHibernate.Tool.hbm2ddl;
using SMS.Infrastructure.Persistence.Logging;
using SMS.Infrastructure.Persistence.Mappings;
using Configuration=NHibernate.Cfg.Configuration;
using System.Data.SqlClient;

namespace SMS.Infrastructure.Persistence
{
    public static class NHibernateHelper
    {
        static readonly ILog Log = LogManager.GetLogger(typeof(NHibernateHelper));
        static Configuration configuration;

        public static ISessionFactory SessionFactory
        {
            get
            {
                return Singleton.sessionFactory;
            }
        }

        // Lazy singleton pattern from http://www.yoda.arachsys.com/csharp/singleton.html
        class Singleton
        {
            static Singleton() { }

            internal static readonly ISessionFactory sessionFactory = CreateSessionFactory();
        }

        public static ISession OpenSession()
        {
            return SessionFactory.OpenSession();
        }

        public static ISession CurrentSession
        {
            get { return SessionFactory.GetCurrentSession(); }
        }

        static ISessionFactory CreateSessionFactory()
        {
            try
            {

                Log.Info("Creating NHibernate session factory");

                NHibernateProfiler.Initialize();

                configuration = new Configuration();

                try
                {
                    // Try to configure NHibernate automagically...
                    configuration.Configure();
                }
                catch (HibernateConfigException e)
                {
                    if (e.InnerException is IOException)
                    {
                        // Otherwise specify a file name manually.
                        configuration.Configure("hibernate.cfg.xml");
                    }
                    else
                        throw;
                }

                Log.Info("Registering custom SMS event listeners");

                RegisterCustomListeners(configuration);

                // Has someone specified a default_schema? No? try and guess
                // it from the (Enterprise Library :/ ) query string.
                if (!configuration.Properties.ContainsKey("default_schema"))
                {
                    Log.Info("Setting default schema");
                    configuration.SetProperty("default_schema", GetDefaultSchema());
                }

                ISessionFactory sessionFactory = Fluently.Configure(configuration)
                    .Mappings(m =>
                    {
                        m.HbmMappings.AddFromAssemblyOf<BusinessUnitTypeMapping>();
                        m.FluentMappings.AddFromAssemblyOf<BusinessUnitTypeMapping>();

                    })
                    .BuildSessionFactory();

                Log.Info("Session factory was configured successfully");

                return sessionFactory;
            }
            catch (Exception ex)
            {
                throw new ArgumentNullException(ex.ToString());
            }
        }

        /// <summary>
        /// NHibernate allows custom event listeners to be registered in 
        /// config files or programmatically. Due to the re-use of configs in
        /// SMS, we chose to do it via code.
        /// 
        /// This is how we extend NHibernate for SMS, and this is why
        /// NHibernate is the best ORM..!
        /// </summary>
        static void RegisterCustomListeners(Configuration config)
        {
            if (config == null)
                throw new ArgumentNullException("config");

            // Event listeners for audit logging.
            //config.SetListener(ListenerType.PreInsert, new AuditEventListener());
            //config.SetListener(ListenerType.PreUpdate, new AuditEventListener());
            //config.SetListener(ListenerType.PreDelete, new AuditEventListener());

            // Event listener for wiring up .NET events between parent/child
            // objects, and the intermediary mapping for Tasks.
            //
            // Warning: be careful with the order in which these listeners are
            // added!!!
            //
            // BindEventsOnLoadListener must come before 
            // TaskAddresseeLoadEventListener for example otherwise OSM Task
            // Decorators don't attach properly.
            config.SetListeners(ListenerType.PostLoad, new IPostLoadEventListener[]
                {
                    new BindEventsOnLoadListener(),
                    new TaskAddresseeLoadEventListener()
                });

        }

        /// <summary>
        /// Optional step: destroy and re-create the database scheme based on
        /// the mapping files. Gives you a totally clean database in between
        /// testing each fixture.
        /// </summary>
        public static void ExportDatabaseSchema(string fileName)
        {
            if (configuration == null)
                CreateSessionFactory();

            Log.InfoFormat("Exporting DDL to {0}", fileName);

            var exporter = new SchemaExport(configuration);
            exporter.SetOutputFile(fileName);
            exporter.Execute(true, false, false);
        }

        public static void ExportFluentMappings(string directoryName)
        {
            Log.InfoFormat("Exporting fluent mappings to {0}", directoryName);
            var model = new PersistenceModel();
            model.AddMappingsFromAssembly(Assembly.GetAssembly(typeof(BusinessUnitTypeMapping)));
            model.WriteMappingsTo(directoryName);
        }

        /// <summary>
        /// hibernate's default_schema is worked out programmatically from the
        /// Enterprise Library connection string. E.g.  
        /// Initial Catalog=OSM2Tests  -->  default_schema = SMS2Tests.dbo
        /// </summary>
        public static string GetDefaultSchema()
        {
            try
            {
                DatabaseSettings settings = DatabaseSettings.GetDatabaseSettings(new SystemConfigurationSource());
                var connectionstring = ConfigurationManager.ConnectionStrings[settings.DefaultDatabase].ConnectionString;
                var initialCatalog = new SqlConnectionStringBuilder(connectionstring).InitialCatalog;
                return String.Format("{0}.dbo", initialCatalog);
            }
            catch (Exception)
            {
                throw new Exception("Could not get default schema from connection string.");
            }
        }
    }
}

Solution

  • I was able to fix a similar problem by removing references to NHProf.