single static instance in multi-thread env.
-
hi, I'm stuck at a multi-thred issue. there is a class HibernateDAO with utility methods. this class is never instanciated, since its methods are static. HibernateDAO has a reference to ISessionFactory, which should be singleton. but this ISessionFactory will be instanciated for each thread seperately (logging will produce the output multiple times). can someone give me a hint why this behaviour occurs even after wrapping the access with _synclock variable?
public class HibernateDAO<T> { static ILog log = LogManager.GetLogger(typeof(HibernateDAO<T>)); static object _synclock = new object(); static ISessionFactory sessionFactory; /// <summary> /// Gets the single session factory instance. /// </summary> /// <value>The session factory.</value> public static ISessionFactory SessionFactory { get { lock (_synclock) { if (sessionFactory == null) { NHibernate.Cfg.Configuration cfg = new NHibernate.Cfg.Configuration().Configure(); cfg.AddAssembly(typeof(T).Assembly); // replace decrypted password string conStr = (string)cfg.Properties["hibernate.connection.connection_string"]; log.Info("Trying to establish connection. Connectionstring: " + conStr); //cfg.SetInterceptor(new LoggingInterceptor()); sessionFactory = cfg.BuildSessionFactory(); } } return sessionFactory; } }
thanks in advance. -
hi, I'm stuck at a multi-thred issue. there is a class HibernateDAO with utility methods. this class is never instanciated, since its methods are static. HibernateDAO has a reference to ISessionFactory, which should be singleton. but this ISessionFactory will be instanciated for each thread seperately (logging will produce the output multiple times). can someone give me a hint why this behaviour occurs even after wrapping the access with _synclock variable?
public class HibernateDAO<T> { static ILog log = LogManager.GetLogger(typeof(HibernateDAO<T>)); static object _synclock = new object(); static ISessionFactory sessionFactory; /// <summary> /// Gets the single session factory instance. /// </summary> /// <value>The session factory.</value> public static ISessionFactory SessionFactory { get { lock (_synclock) { if (sessionFactory == null) { NHibernate.Cfg.Configuration cfg = new NHibernate.Cfg.Configuration().Configure(); cfg.AddAssembly(typeof(T).Assembly); // replace decrypted password string conStr = (string)cfg.Properties["hibernate.connection.connection_string"]; log.Info("Trying to establish connection. Connectionstring: " + conStr); //cfg.SetInterceptor(new LoggingInterceptor()); sessionFactory = cfg.BuildSessionFactory(); } } return sessionFactory; } }
thanks in advance.My guess would be it's because you're using generics (not a threading issue at all). Try running this:
static void Main(string[] args)
{
object o = HibernateDAO<object>.SessionFactory;
object s = HibernateDAO<string>.SessionFactory;
object q = HibernateDAO<object>.SessionFactory;
Console.WriteLine(object.ReferenceEquals(o, s) ? "o==s" : "o!=s");
Console.WriteLine(object.ReferenceEquals(o, q) ? "q==s" : "q!=s");
Console.ReadKey();
}This wil get you:
o!=s q==s
o and s are not the same because you've actually referenced two different classes entirely: One initialized with anobject
and one initialized with astring
. o and q are in fact the same class of typeHibernateDAO<object>
, which is not the same as type HibernateDAO<string>.Standards are great! Everybody should have one!
-
hi, I'm stuck at a multi-thred issue. there is a class HibernateDAO with utility methods. this class is never instanciated, since its methods are static. HibernateDAO has a reference to ISessionFactory, which should be singleton. but this ISessionFactory will be instanciated for each thread seperately (logging will produce the output multiple times). can someone give me a hint why this behaviour occurs even after wrapping the access with _synclock variable?
public class HibernateDAO<T> { static ILog log = LogManager.GetLogger(typeof(HibernateDAO<T>)); static object _synclock = new object(); static ISessionFactory sessionFactory; /// <summary> /// Gets the single session factory instance. /// </summary> /// <value>The session factory.</value> public static ISessionFactory SessionFactory { get { lock (_synclock) { if (sessionFactory == null) { NHibernate.Cfg.Configuration cfg = new NHibernate.Cfg.Configuration().Configure(); cfg.AddAssembly(typeof(T).Assembly); // replace decrypted password string conStr = (string)cfg.Properties["hibernate.connection.connection_string"]; log.Info("Trying to establish connection. Connectionstring: " + conStr); //cfg.SetInterceptor(new LoggingInterceptor()); sessionFactory = cfg.BuildSessionFactory(); } } return sessionFactory; } }
thanks in advance.Your code here does not show HibernateDAO as static. Also it cannot be static as written due to the generics. You have to make the class a strong type and define it explicitely as static in order to get a static class. All you've done is define a static method inside an instance class. You need something like this:
public static class Hibernate
{
...}