-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 
Author Message
 Post subject: Why closing the session?
PostPosted: Fri Jun 08, 2007 5:11 am 
Newbie

Joined: Fri Jun 08, 2007 3:08 am
Posts: 8
Hi!

I am just starting to work with .NET and I was very surprised when I learned that there is nothing similar to EJB, which is natively implemented in the .NET FrameWork. So I was very happy to discover NHibernate but I am not accustomed to use Hibernate, that's why I try to retrieve something nearer to EJB and I need opinions about this implementation.


I do not want that the user cares about the session, like the EntityManager in EJB, that's why I use a singleton pattern to obtain it and I keep it alive in order to use lazy loading. Is it possible to keep this session alive during all the application ?

Code:
internal class SessionFactory {

    private static SessionFactory apoSession = null;
    private static ISession session;
    private static ISessionFactory factory;

    private SessionFactory(string assembly) {
        Configuration config = new Configuration();
        config.AddAssembly(Assembly.LoadFrom(assembly));
        factory = config.BuildSessionFactory();
        session = factory.OpenSession();
    }

    internal static ISession CreateSessionWith(String assembly) {
        if (apoSession == null)
            apoSession = new SessionFactory(assembly);
        return session;
    }

    internal static void CloseSession() {
        session.Flush();
        session.Dispose();
        factory.Close();
    }
}



After this, I try to develop somethink like an EJB Session which could be generic to all the entities.

Code:
public class EntitiesManager<T> {

    private static ISession m_Session;

    public EntitiesManager(string assembly) {
        m_Session = SessionFactory.CreateSessionWith(assembly);       
    }

    /*public static ISession Session {
        get { return m_Session; }
    }*/

    public void SaveOrUpdate(object o) {
        ITransaction tx = null;
        try {
            tx = m_Session.BeginTransaction();
            m_Session.SaveOrUpdate(o);
            tx.Commit();
        } catch (Exception ex) {
            Console.Write(ex);
            tx.Rollback();
        }
    }

    public T Get(int id) {
        T t = default(T);
        ITransaction tx = null;
        try {
            tx = m_Session.BeginTransaction();
            t = (T)m_Session.Get(typeof(T), id);
            tx.Commit();
        } catch (Exception ex) {
            Console.Write(ex);
            tx.Rollback();
        }
        return t;
    }

    public void Delete(object o) {
        ITransaction tx = null;
        try {
            tx = m_Session.BeginTransaction();
            m_Session.Delete(o);
            tx.Commit();
        } catch (Exception ex) {
            Console.Write(ex);
            tx.Rollback();
        }
    }
}



Finally after implementing the entities classes and the mapping files I can use it like this:

Code:
EntitiesManager<Client> cm = new EntitiesManager<Client>(assembly);
EntitiesManager<Product> pm = new EntitiesManager<Product>(assembly);


/*=====Write a Client=====*/
Client c1 = new Client();
c1.FirstName = "Dupond";
c1.LastName = "Roger";
cm.SaveOrUpdate(c1);

/*=====Read the Client=====*/
Client c10 = cm.Get(1);
Console.WriteLine("Client\t Id: {0}\t FirstName: {1}\t LastName: {2}", c10.Id, c10.FirstName, c10.LastName);

/*=====Write a Product=====*/
Product p1 = new Product();
p1.Name = "Mir vaisselle";
p1.Price = 1.09f;
pm.SaveOrUpdate(p1);

/*=====Read the Product=====*/
Product p10 = pm.Get(1);
Console.WriteLine("Product\t Id: {0}\t PType: {1}\t Name: {2}\t Price: {3}", p10.Id, p10.ProductType.Name, p10.Name, p10.Price);




My real problem is that contrary to EJB, I must initialize the EntitiesManager (of course i can't use @EJB EntitiesManager<...> em) and so I don't know how to implement an automaticaly destruction and closing of the Session and the EntitiesManager.
If I add a Close() in the generic EntitiesManager which call SessionFactory.CloseSession(), the user will use it many times to close all his EntitiesManagers (<Client>, <Product>...) which will throws Exception.

I think about building a counter in the SessionFactory which will know the number of EntitiesManager, incremented when I make a new EntitiesManager and when it reach zero, by calling their Close(), SessionFactory.CloseOperation will be called.


Is it a good implementation, a anti pattern ? Will I encounter problems of optimization ? Does it already exist something similar which is already implemented ? I read a lot about NHibernate but I didn't found something similar...


Thx a lot!


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 12, 2007 10:43 am 
Newbie

Joined: Fri Jun 08, 2007 3:08 am
Posts: 8
up


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jun 12, 2007 12:09 pm 
Regular
Regular

Joined: Wed Apr 25, 2007 4:18 am
Posts: 51
Location: Belarus, Gomel
Hi Apo007!

You can't really have one (permanent) session during all application lifecycle. Mainly because there is no simple way to recover session after ANY NHibernate exception (it is documented) - so if you'll get into any of your catch blocks - the only sane think you can do (after rollback of couse) is to close session and even dispose ALL entities and collections you got from this session.
Of course you may try to recreate session and even try to reattach all your persistent entities to this new session - but I don't think you'll succeed in it. I spend too many time on this problem and don't have suitable solution.

So you'd better try another approach - maybe something like webApps - load in one session, detach objects, work with them and save in another session (and forget about lazy loading, as it just don't work without permanent session) :(

I'd say there must be walkthrough about creating rich/thick WinForms applications that use NHibernate somewhere, but I don't find one till now - please let me know if you'll find one...

_________________
WBR, Igor


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 3 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.