4

I was trying to implement Multiple DB connected Fluent NHibernate sample Application.

My Fluent NHibernate Repository is as follows:

namespace RepositoryExample.Repository.NHibernate {
    public class NHibernateRepository<T> : IRepository<T> where T : class
    {
        protected static Configuration config;
        private static readonly ISessionFactory _globalSessionFactory = new Configuration().Configure().BuildSessionFactory();

    protected static IDictionary<string, ISessionFactory> _allFactories;
    public NHibernateRepository()
    {
        IDictionary<string, string> dataBases = new Dictionary<string, string>();
        dataBases.Add("Monkey", @"Data Source=.\SQLEXPRESS;AttachDbFilename='MonkeyDB.mdf';Integrated Security=True;User Instance=True");
        dataBases.Add("Banana", @"Data Source=.\SQLEXPRESS;AttachDbFilename='Banana.mdf';Integrated Security=True;User Instance=True");
        // Error at below line (See stack trace for deatils below)
        _allFactories = new Dictionary<string, ISessionFactory>(dataBases.Count);
        foreach (var dataBase in dataBases)
        {
            config = Fluently.Configure()
                .Database(
                MsSqlConfiguration.MsSql2008.ConnectionString(dataBase.Value))
                .Mappings(m => m.FluentMappings.AddFromAssemblyOf<NHibernateRepository<T>>())
                .BuildConfiguration();
            _allFactories.Add(dataBase.Key, config.BuildSessionFactory());
        }
    }
    public ISession GetSession()
    {
        var currentIdentifier = GetCurrentIdentifier();
        return _allFactories[currentIdentifier].OpenSession();
    }

    private string GetCurrentIdentifier()
    {
        if (typeof(T).ToString().Contains("Banana"))
        {
            return "Banana";
        }
        else
        {
            return "Monkey";
        }
    }
    public void Save(T value)
    {
        var sessioned = GetSession();
        using (var transaction = sessioned.BeginTransaction())
        {
            sessioned.Save(value);
            transaction.Commit();
        }
    }
    public void GenerateSchema(SanityCheck AreYouSure)
    {
        new SchemaExport(config).Create(true,true);
    } }

}

And I'm calling as follows:

public class NHibernateIntegrationTest
    {

        static void Main(string[] args)
        {
            var repo = new NHibernateRepository<NHibernateIntegrationTest>();
            repo.GenerateSchema(SanityCheck.ThisWillDropMyDatabase);
        }
    }

Error at:

_allFactories = new Dictionary<string, ISessionFactory>(dataBases.Count);

It is in NHibernateRepository class's default constructor.

StackTrace:
System.TypeInitializationException was unhandled
  Message=The type initializer for 'RepositoryExample.Repository.NHibernate.NHibernateRepository`1' threw an exception.
  Source=RepositoryExample
  TypeName=RepositoryExample.Repository.NHibernate.NHibernateRepository`1
  StackTrace:
       at RepositoryExample.Repository.NHibernate.NHibernateRepository`1..ctor() in C:\Documents and Settings\pavankumarn\My Documents\Downloads\nhibernate-repository-example\RepositoryExample\Repository\NHibernate\NHibernateRepository.cs:line 44
       at Test.NHibernateIntegrationTest.Main(String[] args) in C:\Documents and Settings\pavankumarn\My Documents\Downloads\nhibernate-repository-example\Test\NHibernateIntegrationTest.cs:line 17
       at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: NHibernate.Cfg.HibernateConfigException
       Message=An exception occurred during configuration of persistence layer.
       Source=NHibernate
       StackTrace:
            at NHibernate.Cfg.ConfigurationSchema.HibernateConfiguration..ctor(XmlReader hbConfigurationReader, Boolean fromAppSetting)
            at NHibernate.Cfg.ConfigurationSchema.HibernateConfiguration..ctor(XmlReader hbConfigurationReader)
            at NHibernate.Cfg.Configuration.Configure(XmlReader textReader)
            at NHibernate.Cfg.Configuration.Configure(String fileName, Boolean ignoreSessionFactoryConfig)
            at NHibernate.Cfg.Configuration.Configure(String fileName)
            at NHibernate.Cfg.Configuration.Configure()
            at RepositoryExample.Repository.NHibernate.NHibernateRepository`1..cctor() in C:\Documents and Settings\pavankumarn\My Documents\Downloads\nhibernate-repository-example\RepositoryExample\Repository\NHibernate\NHibernateRepository.cs:line 17
       InnerException: System.IO.FileNotFoundException
            Message=Could not find file 'C:\Documents and Settings\pavankumarn\My Documents\Downloads\nhibernate-repository-example\Test\bin\Debug\hibernate.cfg.xml'.
            Source=mscorlib
            FileName=C:\Documents and Settings\pavankumarn\My Documents\Downloads\nhibernate-repository-example\Test\bin\Debug\hibernate.cfg.xml
            StackTrace:
                 at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
                 at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy)
                 at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize)
                 at System.Xml.XmlDownloadManager.GetStream(Uri uri, ICredentials credentials)
                 at System.Xml.XmlUrlResolver.GetEntity(Uri absoluteUri, String role, Type ofObjectToReturn)
                 at System.Xml.XmlTextReaderImpl.OpenUrlDelegate(Object xmlResolver)
                 at System.Threading.CompressedStack.runTryCode(Object userData)
                 at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
                 at System.Threading.CompressedStack.Run(CompressedStack compressedStack, ContextCallback callback, Object state)
                 at System.Xml.XmlTextReaderImpl.OpenUrl()
                 at System.Xml.XmlTextReaderImpl.Read()
                 at System.Xml.XmlTextReader.Read()
                 at System.Xml.XmlCharCheckingReader.Read()
                 at System.Xml.XsdValidatingReader.Read()
                 at System.Xml.XPath.XPathDocument.LoadFromReader(XmlReader reader, XmlSpace space)
                 at System.Xml.XPath.XPathDocument..ctor(XmlReader reader, XmlSpace space)
                 at System.Xml.XPath.XPathDocument..ctor(XmlReader reader)
                 at NHibernate.Cfg.ConfigurationSchema.HibernateConfiguration..ctor(XmlReader hbConfigurationReader, Boolean fromAppSetting)
            InnerException: 

I'm not using hibernate.cfg.xml, since I'm configuring the session factory Fluently. But Inner stack trace is showing that hibernate.cfg.xml file is not found. See the below screenshot. enter image description here

navule
  • 3,212
  • 2
  • 36
  • 54
  • Please delete your other question that leads to this one. You shouldn't really be doing that on Stack Overflow. Also, you could try cross-posting your question to nhusers group at: http://groups.google.com/group/nhusers – Miroslav Popovic Jun 28 '12 at 23:31
  • Also, when you get to 75 reputation points, you'll have the ability to set bounties, which will make your question featured and a lot more exposed - http://stackoverflow.com/privileges/set-bounties – Miroslav Popovic Jun 28 '12 at 23:36

1 Answers1

3

You have very clear error message in your most inner exception:

Could not find file 'C:\Documents and Settings\pavankumarn\My Documents\Downloads\nhibernate-repository-example\Test\bin\Debug\hibernate.cfg.xml'.

You probably have that file in your Test project. Set its Build Action to None and Copy to Output Directory to Copy if newer.


Edit:

Actually, the problem was not in constructor itself, but in a line above it:

private static readonly ISessionFactory _globalSessionFactory = new Configuration().Configure().BuildSessionFactory();

Here you are creating another NHibernate Configuration, using the defaults. And by default, when you create a new Configuration(), it will try to load from app.config or hibernate.cfg.xml.

Remove that line. I don't see the _globaSessionFactory used anywhere.

Miroslav Popovic
  • 12,100
  • 2
  • 35
  • 47
  • But I'm using Fluent Nhibernate. I did not use hibernate.cfg.xml anywhere in my repository too. – navule Jun 29 '12 at 07:53
  • How does your NHibernate initialization looks like? If you are using the same code as in the article you are referring to, then you are not using FluentNHibernate and will probably need to have `hibernate.cfg.xml` file also. Could you post your initialization code also? – Miroslav Popovic Jun 29 '12 at 08:53
  • what ever the code I posted apart from entites and mappings that is all there in the question. Initialization code what I understood is you are asking about Configuring ISessionFactory. If it so, then it is already there in the code above in the default constructor `public NHibernateRepository()` – navule Jun 29 '12 at 10:02
  • 1
    Sorry, I failed to see that... For some reason the default NHibernate configuration is triggering loading from config file. I'll try to research a little more on this. – Miroslav Popovic Jun 29 '12 at 10:32
  • Strange thing that can be seen in your exception - the stack trace should contain `FluentNHibernate.Cfg.Fluently.Configure()` method, and then a constructor for `FluentNHibernate.Cfg.FluentConfiguration` ctor, but instead it calls `NHibernate.Cfg.Configuration.Configure()` directly ?!? This is something that would happen if you call `new Configuration().Configure()` instead of `Fluently.Configure()`. Please check your `Fluently.Configure()` method signature. – Miroslav Popovic Jun 29 '12 at 11:19
  • the line `protected static Configuration config; ` has `Configuration` pertaining to Metadata Class `NHibernate.Cfg.Configuration`. Is it ok to asssign config with Fluent Config (this is what I'm doing here)?? – navule Jun 29 '12 at 12:37
  • Your comment made me realize there are more initializations above the constructor. See my edit. – Miroslav Popovic Jun 29 '12 at 12:54
  • 1
    We shouldn't be doing any more comments on this post... it's getting too long. You might create another question instead. Here's just this answer: you are calling `dataBases.Values.ToString()` which will return something like `"List"` as a result, since `dataTables.Values` is a list. You should just use a single item from your foreach instead - `dataBase.Value`. – Miroslav Popovic Jun 29 '12 at 14:36