Nhibernate2.1.0.4000を実行している.Net3.5で動作するWebサイトがあります。ProxyFactoryとしてSpringを使用しています。
すべてが正常に動作します。ウィザードを使用して、プロジェクトを.Net4.0にアップグレードしようとしました。すべて順調に進みました。
しかし、コードがNhibernateで何かを行おうとするとすぐに、System.ExecutionEngineExceptionという非常に不親切な例外が発生します。スタックトレースや内部例外はありません。
NhibernateHelperクラス(以下)を使用していて、それを試してみたところ、セッションは正常に構成されました(例外なし)。詳細は、.net3.5バージョンから変更されていません。
DBから何かを取得する最初の試みは失敗します
セッションは、リクエストの開始時にハンドラーで開かれます(以下には示されていません)。また、アプリケーションの開始時に設定されたユニティを使用しています(それが何らかの関係を持っているかどうかはわかりません)
Nhibernateへの最初の呼び出しは
var emp = NHibernateHelper.CurrentSession.Get<SMS.DomainModel.Employee>(-200694);
何かを意味し、何かを続けるためのエラーメッセージが欲しいだけです。
NhibernateProfilerを見てみましたが、登録されているのはセッションの開始だけです。
どんな助けでも大歓迎です
NhibernateHelperクラスは次のとおりです
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.");
}
}
}
}