1

I'm developing a website using Asp .Net MVC and NHibernate as ORM tool. I just implemented some patterns using some principles. These are IoC, Service-Repository and UoW.

I'm using almost all features of NHibernate in terms of Caching like below

  • Lazy Loading
  • 2nd Level Cache
  • Query Cache
  • Entity Cache

Up to now everything was fine, I can load whole web site in 1 second almost 7,5 MB size in total(mostly images from Azure Storage) without Asp .Net MVC 's outputcache with above infrastructure but this action is happening when i load the web site for the second time.

The big problem is NHibernate SessionFactory adds almost 15 seconds to uptime of the project when it's first load and this is unacceptable.

I have 25 entities and so their mappings actually, why it takes so much time for the first time?

Here my configuration for Nhibernate

public static ISessionFactory GetSessionFactory()
{
        return Fluently.Configure()
       .Database(MsSqlConfiguration.MsSql2012
       .Raw("connection.isolation", "ReadCommitted")
       .ConnectionString("connectionString")
       .Mappings(gX => gX.FluentMappings.AddFromAssemblyOf<MyEntity>())
       .Cache(gX => gX.ProviderClass<SysCacheProvider>()
       .UseSecondLevelCache()
       .UseQueryCache())
       .BuildSessionFactory();
 }

I don't have any problem of the create process of the SessionFactory by the way. The only problem is the up time of my project for the first time. I just solved many problems about with caching strategies but couldn't figured out the SessionFactory.

Any idea or suggestion about it? Thanks

revolver
  • 95
  • 1
  • 8

1 Answers1

2

Couple of comments that might help you.

  1. You can serialise your sessionfactory after its been built. See this blog post for more info. Or Google serialise sessionfactory nhibernate as there are alot of articles

  2. If this is a web site then I would always make sure it is spun up and never stops on inactivity. One way is to sign up to a free account on uptime robot which pings your site (asks for headers) every 5 minutes hence keeping it alive. However on any deploy that changes schema you are still going to get a slow start up time.

Below is the way I serialise the NHibernate SessionFactory you should be able to adapt it with the blog post above to fit your needs. I have seen people use the #Debug directive or file creation times to see whether the file needs to be regenerated.

  private static ISessionFactory SetUpNhibernate()
    {

        var file = HttpContext.Current.Server.MapPath("~/App_Data/cfg-serialised.xml");
        IFormatter serializer = new BinaryFormatter();
        var cfg = new Configuration();

        if (File.Exists(file))
        {
            using (var stream = File.OpenRead(file))
            {
                cfg = serializer.Deserialize(stream) as Configuration;
            }
        }
        else
        {
            var mapper = new ModelMapper();
            mapper.AddMappings(typeof(CmsMeta).Assembly.GetTypes());
            var mapping = mapper.CompileMappingForAllExplicitlyAddedEntities();
            cfg.Configure();
            cfg.AddDeserializedMapping(mapping, "Domain");
            using (var stream = File.OpenWrite(file))
            {
                serializer.Serialize(stream, cfg);
            }
        }

        return cfg.BuildSessionFactory();
    }
Rippo
  • 22,117
  • 14
  • 78
  • 117
  • Thanks for your comments. I m not sure the first suggestion is going to be work with the fluent configuration. I read the related article which solves the issue on hbm.xml files but not fluent api actually. I m going to give a try btw. Actually the seccond suggestion is a good trick and i just impelement a similar solution this morning and works well now. I m not sure it s a good solution but it works. – revolver May 13 '15 at 11:35
  • gone from around 20 secs to about 8 secs, just over half. Its still slow but more manageable. The solution should work with fluent (I am sure there are articles out there) – Rippo May 13 '15 at 11:42
  • Ok. I will give a try with my setup. Thanks @Rippo – revolver May 13 '15 at 12:14
  • Putting a refresh method on client side solved the whole issue. Saved almost 12-13 seconds. Thanks – revolver May 20 '15 at 06:57