NHibernate + IIS7.5 throws "A session factory has already been configured with the key of nhibernate.current_session"
Using S#arp Architecture 2.3 RC
, I am trying to publish two websites which use -mostly- the same codebase. The first of the applications I publish runs correctly, however, upon deploying and trying to run the second application, I开发者_JAVA百科 get the following exception:
Access to the path 'C:\Windows\TEMP\nhibernate.current_session--851346262.bin' is denied.
When I refresh the window, I then get this exception:
A session factory has already been configured with the key of nhibernate.current_session
I have even tried loading them in separate Application Pools and the error persists. I don't understand how is it that my two applications' sessions are colliding on IIS, whereas they run just fine with Visual Studio.
FYI, I am trying to run them on Windows Server 2008 R2 + IIS 7.5
Any help?
I "fixed" it by changing the application pool's identity to one with more permission e.g. LocalSystem. Not a suitable fix if you have access to the source.
For the case where it is a single website using #arch and NHibernateConfigurationFileCache. The problem most likely comes from
- NHibernateConfigurationFileCache using Path.GetTempPath() to persist the config
- The website is run using application pool under network service or application pool identity
- The identity doesn't have write permission to the temp path
The better solution will be to change the code to use a temp path where the identity will have permission, or
Grant write permission to the temp path for the identity (e.g. grant write permission on c:\windows\temp to
IIS APPPOOL\CustomAppPool)
It looks like S#arp Architecture tries to use the same NHibernate session factory for both applications. It maybe colliding because it uses the same default 'factory key' (nhibernate.current_session) for both web apps when it persists configuration on disk. Should you be using different 'factory keys'? In order to do this you can read the FAQ section about multiple databases (although you don't have multiple databases, your solution may be the same):
Q: How do I add support for multiple databases?
A:: To add support for an additional database to your project:
Create an NHibernateForOtherDb.config file which contains the connection string to the new database
Within YourProject.Web.Mvc/Global.asax.cs, immediately under the NHibernateSession.Init() to initialize the first session factory, an additional call to NHibernateSession.AddConfiguration(). While the first NHibernate initialization assumes a default factory key, you'll need to provide an explicit factory key for the 2nd initialization. This factory key will be referred to by repositories which are tied to the new database as well...
Looking at S#arp sources I found that they use following logic to create file on disk:
var fileName = string.Format(
"{0}-{1}.bin",
configKey,
Assembly.GetCallingAssembly().CodeBase.GetHashCode());
So if you don't want to change config/factory key you can try calling this code from different assembly.
EDIT:
It looks like NHibernateSession.Init
does not take overload that lets you specify factory key. But it has other public methods that you can call instead of Init:
NHibernateSession.InitStorage(storage);
try {
NHibernateSession.AddConfiguration("%PUT YOUR OWN FACTORY KEY%", ...);
} catch {
NHibernateSession.Storage = null;
throw;
}
精彩评论