I´m using NHibernate 3 on a new desktop project. I’ve read about serialize the Configuration Object. I did it but, sometimes it didn´t work. I’m started to think that it´s working only when i start up the app (serialize the configuration object), then close it, and startup again (few seconds later). But if i wait some minutes it didn´t work. I´m talking about 45+ seconds. Other Strange thing if that this just happen on a few machines not all. Some work as expected slow the first time, but faster the nexts startups.
Here is my configuration:
the class that create the configuration and session factory
class NHibernateUnitOfWorkFactory : IUnitOfWorkFactory
{
public NHibernateUnitOfWorkFactory(string nhibernateConfigPath)
{
String serializablefilePath = "configuration.serialized";
try
{
if (IsConfigurationFileValid(serializablefilePath))
{
Configuration = LoadConfigurationFromFile(serializablefilePath);
}
else
{
// configuration is immutable, store last returned value
Configuration = new Configuration();
Configuration.Configure(nhibernateConfigPath);
Configuration.AddAssembly(typeof(ObjectEntity).Assembly);
SaveConfigurationToFile(serializablefilePath, Configuration);
new SchemaUpdate(Configuration).Execute(true, true);
}
//NHibernateSchemaExport();
}
catch (Exception ex)
{
throw new GenericRepositoryException(
string.Format("Error while configuring NHibernate: {0}.", ex.Message)
, ex
);
}
try
{
SessionFactory = Configuration.BuildSessionFactory();
}
catch (Exception ex)
{
throw new GenericRepositoryException(
string.Format("Error while building NH session factory: {0}.", ex.Message)
, ex
);
}
}
private Boolean IsConfigurationFileValid(String ConfigFile)
{
//return File.Exists(ConfigFile);
var ass = typeof(ObjectEntity).Assembly; //Assembly.GetCallingAssembly();
if (ass.Location == null)
return false;
var configInfo = new FileInfo(ConfigFile);
var assInfo = new FileInfo(ass.Location);
if (configInfo.LastWriteTime < assInfo.LastWriteTime)
return false;
return true;
}
private static void SaveConfigurationToFile(String ConfigFile, Configuration configuration)
{
var file = File.Open(ConfigFile, FileMode.Create);
var bf = new BinaryFormatter();
bf.Serialize(file, configuration);
file.Close();
}
private static Configuration LoadConfigurationFromFile(String ConfigFile)
{
try
{
var file = File.Open(ConfigFile, FileMode.Open);
var bf = new BinaryFormatter();
var config = bf.Deserialize(file) as Configuration;
file.Close();
return config;
}
catch (Exception)
{
return null;
}
}
protected ISessionFactory SessionFactory { get; private set; }
protected Configuration Configuration { get; private set; }
/// <summary>
/// Generates table structure inside specified database.
/// </summary>
public void NHibernateSchemaExport()
{
new SchemaExport(this.Configuration).Execute(false, true, false);
}
#region IUnitOfWorkFactory Members
public IUnitOfWork BeginUnitOfWork()
{
return new NHibernateUnitOfWork(this.SessionFactory.OpenSession());
}
public void EndUnitOfWork(IUnitOfWork unitOfWork)
{
var nhUnitOfWork = unitOfWork as NHibernateUnitOfWork;
if (unitOfWork != null)
{
unitOfWork.Dispose();
unitOfWork = null;
}
}
#endregion
#region IDisposable Members
public void Dispose()
{
if (this.SessionFactory != null)
{
(this.SessionFactory as IDisposable).Dispose();
this.SessionFactory = null;
this.Configuration = null;
}
}
#endregion
}
xml configuration
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2" >
<reflection-optimizer use="true"/>
<session-factory name="NHibernate.Test">
<property name="connection.driver_class">NHibernate.Driver.OracleClientDriver</property>
<property name="connection.connection_string">
User Id=xx;
Password=xx;
Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=
(PROTOCOL=TCP)(HOST=192.168.100.xx)(PORT=1521)))
(CONNECT_DATA=(SERVICE_NAME=XE)));
</property>
<property name="show_sql">false</property>
<property name="dialect">NHibernate.Dialect.Oracle10gDialect</property>
<property name="query.substitutions">true 1, false 0, yes 'Y', no 'N'</property>
<property name="proxyfactory.factory_class">NHibernate.ByteCode.LinFu.ProxyFactoryFactory, NHibernate.ByteCode.LinFu</property>
<property name="cache.use_query_cache">false</property>
<property name="cache.use_second_level_cache">false</property>
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
</session-factory>
</hibernate-configuration>
Any idea to improve the startup time?
Serialization only speeds up building the Configuration (
config = new Configuration().Add...vsconfig = bf.Deserialize(file)) not building the sessionfactory, which does a lot of other stuff like generating the proxies, connecting to the database and so on. It’s most likely a slow connection to the server or a slow server which is responsible for the delay.Also it would be better to use
usingto prevent leaking FileHandles when exceptions occure