views:

248

answers:

3

I'm using NHibernate + Fluent to handle the database in my application. So far I've been using a SessionSource to create my ISession objects. I'm a bit confused now about what comes from NHibernate or Fluent, and what I really should use for creating my sessions.

ISession comes from NHibernate, and the SessionSource from Fluent. I create the SessionSource from a FluentConfiguration, and currently use the SessionSource to create sessions. This is my function to create sessions. The FluentConfiguration and SessionSource is reused:

if (_sessionSource == null)
{
    _cfg = Fluently.Configure().Database(SQLiteConfiguration.Standard.ShowSql().UsingFile("test.db"));
    _sessionSource = new SessionSource(_cfg.BuildConfiguration().Properties, new MappingsPersistenceModel());
    var session = _sessionSource.CreateSession();
    _sessionSource.BuildSchema(session);
    return session;
}
return _sessionSource.CreateSession(); 

Does this look reasonable? It sounds more appealing to use a ISessionFactory to create sessions though, so I tried using one. This comes from NHibernate, so I don't know if that's why it is a problem, but it fails when my sessions are created from an ISessionFactory.

// Done once: 
_sessionFactory = _cfg.BuildSessionFactory();

// Done each time a session is requested: 
_sessionFactory.OpenSession()

Using this I get a MappingException when using the session, saying "No persister for: MyProject.Model.SomeModelClass".

Should I keep using the SessionSource? Or am I missing something regarding the ISessionFactory?

+2  A: 

I know how you feel! The divide between fluent and NH can be rather confusing at the start. In my opinion you should not use SessionSource, AFAIK it is only really useful in testing scenarios. I recomend that you just use the ISessionFactory directly from NH.

Can you post your error? You seem to be using it correctly, so probably there is something wrong with the configuration or the cfg object.

UpTheCreek
+1  A: 

Please see this class may be help full for you.I have write methods for create factory and session.

 public class Common
    {
        public const string NHibernateSessionKey = "nhibernate.session.key";

        public static string ConnString
        {
            get
            {
                return System.Configuration.ConfigurationManager.ConnectionStrings["JewelSoftMySqlConn"].ConnectionString;
            }
        }

        public static ISessionFactory  FACTORY = CreateFactory();

        static ISessionFactory CreateFactory()
        {
            Configuration config = new Configuration();
            IDictionary props = new Hashtable();

            props.Add("hibernate.dialect", "NHibernate.Dialect.MySQLDialect");
            props.Add("hibernate.connection.provider", "NHibernate.Connection.DriverConnectionProvider");
            props.Add("hibernate.connection.driver_class", "NHibernate.Driver.MySqlDataDriver");
            props.Add("hibernate.connection.connection_string", Common.ConnString);
            config.AddProperties(props);

            config.AddInputStream(new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(Resource.Models_hbm)));

            return config.BuildSessionFactory();
        }

        public static ISession GetCurrentSession()
        {
            ISession currentSession = null;
            HttpContext context = HttpContext.Current;
            if (context != null)
            {
                currentSession = context.Items[NHibernateSessionKey] as ISession;
                if (currentSession == null)
                {
                    currentSession = FACTORY.OpenSession();
                    context.Items[NHibernateSessionKey] = currentSession;
                }
            }
            else//will work non web request, like in test environment
                currentSession = FACTORY.OpenSession();

            return currentSession;
        }
    }
Pankaj
Thanks for the reply. From what I can see you're not using Fluent here? Only NHibernate? My problem is related to the use of Fluent and NHibernate together..
stiank81
Sorry @@Bambuska...and thanks for new idea for me..for a long time i also want to learn this method to use Nhibernate
Pankaj
No problem! Check out the Fluent Wiki. It's very nicely written, and should be of good help to get started: http://wiki.fluentnhibernate.org/Getting_started
stiank81
Thanks @Bambuska
Pankaj
+3  A: 

The problem seems to be that the SessionFactory doesn't know about the mappings since they are only given to the SessionSource. Adding the mappings during the fluent configuration and getting the factory from this seems to help. This gave me what looks like a better solution. Does this look reasonable to those of you with more experience on this?

private static ISession CreateSession()
{
    if (_sessionFactory == null)
    {
        _sessionFactory = Fluently.Configure().
            Database(SQLiteConfiguration.Standard.ShowSql().UsingFile("test.db")).
            Mappings(m => m.FluentMappings.AddFromAssemblyOf<MappingsPersistenceModel>()).
            BuildSessionFactory();
    }
    return _sessionFactory.OpenSession();
}
stiank81
+1 Was just about to write something like this. This is the way to go, well done. Note that this example (similar at least) is in the excellent tutorial of FluentNH. (note: after two days you can mark your own answer as accepted)
Abel
Thanks for the comment and confirmation that I'm on the right way. Really appreciate the help you've given me!
stiank81