Reputation: 1739
We're building a mobile application, and we're evaluating NHibernate + Fluent for use with it. The problem is, the first time we create the ISessionFactory, it takes a full 2 minutes. even though the table structure is very simple (3 tables).
each call after that is extremely fast.
what i'd like to do is either cache the ISessionFactory between application restarts, or somehow speed up the creation of it in the first place.
Any ideas on if it's possible to cache? from all my reading, there's not much speeding it up.
Upvotes: 3
Views: 1484
Reputation: 18796
You can serialize and save the configuration and load that up the second time around to reduce the time it takes to create. Tho if you make changes you need to blow away the old config and serialize a new version, otherwise you will be loading up old configuration.
I can't remember the code to do this tho, will try dig up an example.
Edit: http://vimeo.com/16225792
In this video at about 24 minutes in Ayende discusses Configuration Serialization.
Upvotes: 4
Reputation: 9548
Defining your ISessionFactory as a static variable (Shared for VB) and instantiating it only once upon application startup is how web apps get around this. I realize this may pose a challenge for a mobile app with memory efficiency demands but depending on the mobile platform you're using the application lifetime may not be as short as one would fear...
public class NHHelper {
private static string _connectionString;
private static ISessionFactory _sessionFactory;
private static ISessionFactory SessionFactory {
get {
if (_sessionFactory == null) {
_sessionFactory = Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2008.ShowSql()
.ConnectionString(p => p.Is(_connectionString)))
.Mappings(m => m.FluentMappings.AddFromAssembly(Assembly.GetAssembly(typeof(NHHelper))))
.BuildSessionFactory();
}
return _sessionFactory;
}
}
// this is called once upon application startup...
public static void WarmUpSessionFactory(string connectionString) {
_connectionString = connectionString;
var factory = SessionFactory;
}
// this is what you call to get a session for normal usage
public static ISession OpenSession() {
return SessionFactory.OpenSession();
}
}
Upvotes: 2
Reputation: 11651
When building the Configuration and ISessionFactory, NHibernate is parsing configuration and mappings to build up its runtime data structures. (This is true of EF and LINQ-to-SQL too, though its hidden within the context.) There is not much that can be done to eliminate this cost, though 2 minutes seems awfully long. Timing this code:
var stopwatch = new Stopwatch();
stopwatch.Start();
var cfg = new Configuration();
cfg.Configure();
var sessionFactory = cfg.BuildSessionFactory();
stopwatch.Stop();
Console.WriteLine("Startup time was " + stopwatch.ElapsedMilliseconds + "ms");
It's a demo project and only has a few classes and mappings, but it took ~850 ms without the debugger attached. With the debugger attached, it was around 2 seconds.
Have you tried profiling your app to see where it is spending the 2 minutes?
Upvotes: 0