Should session and factory be closed?
Asked Answered
L

1

0

I'm using Hibernate 5.0.2.Final with a Data-Source connection (On a Tomcat 8.0.15) and started to ask myself if it's necessary to not only close the Session but also the SessionFactory?

Right now it looks like this:

public static List<HibernateList> getHibernateList() {
        Session session = null;
        final String hql = "SELECT H FROM myhibernate.MyHibernate";
        try {
            SessionFactory factory = HibernateUtil.getSessionFactory();
            session = factory.openSession();
            session.beginTransaction();

            Query query = session.createQuery(hql);

            return query.list();
        } catch (HibernateException hibex) {
            Logger.getLogger(Hibernatepicker.class.getName()).log(Level.INFO, null, hql);
            Logger.getLogger(Hibernatepicker.class.getName()).log(Level.SEVERE, null, hibex);
        } finally {
            try {
                if (session != null) {
                    session.close();
                }
            } catch (HibernateException hibex) {
            }//Nothing I could do...
        }
        return null;
    }

Some details from the hibernate.cfg.xml

<property name="hibernate.connection.datasource">java:comp/env/jdbc/sqlserv</property>        
<property name="current_session_context_class">thread</property> 
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property> 
<property name="hbm2ddl.auto">auto</property> 
<property name="show_sql">false</property>       
<property name="hibernate.generate_statistics">true</property>  

And the HibernateUtil:

public class HibernateUtil {
private static final SessionFactory sessionFactory;

static {
    try {
        Configuration cfg = new Configuration();
        sessionFactory = cfg.configure("hibernate.cfg.xml").buildSessionFactory();
    } catch (Throwable ex) {
        Logger.getLogger(HibernateUtil.class.getName()).log(Level.SEVERE, null, ex);
        throw new ExceptionInInitializerError(ex);
    }
}

public static SessionFactory getSessionFactory() {
    return sessionFactory;
}
}

I'm undecided whether it's necessary or not to call this method in the finally-block instead of only closing the session:

public static void disconnect(Session session, SessionFactory factory) {
        try {
            if (session != null) {
                session.close();
            } else {
                Logger.getLogger(HibernateUtil.class.getName()).log(Level.INFO, null, "Session is Null");
        }

    } catch (HibernateException | NullPointerException hibex) {
        Logger.getLogger(HibernateUtil.class.getName()).log(Level.INFO, null, "Couldn't close session, but there's nothing we can do...");
        Logger.getLogger(HibernateUtil.class.getName()).log(Level.SEVERE, null, hibex);
    }
    try {
        if (factory != null) {
            factory.close();
        } else {
            Logger.getLogger(HibernateUtil.class.getName()).log(Level.INFO, null, "Factory is Null");
        }

    } catch (HibernateException | NullPointerException hibex) {
        Logger.getLogger(HibernateUtil.class.getName()).log(Level.INFO, null, "Couldn't close session, but there's nothing we can do...");
        Logger.getLogger(HibernateUtil.class.getName()).log(Level.SEVERE, null, hibex);
    }
}
Limicoline answered 20/10, 2015 at 12:14 Comment(0)
R
2

You should not close your SessionFactory on every query. Your SessionFactory should be initialised only once per application.

From the hibernate documentation.

The main contract here is the creation of Session instances. Usually an application has a single SessionFactory instance and threads servicing client requests obtain Session instances from this factory. The internal state of a SessionFactory is immutable. Once it is created this internal state is set. This internal state includes all of the metadata about Object/Relational Mapping.

Implementors must be threadsafe.

Register answered 20/10, 2015 at 13:51 Comment(3)
Great, thanks for the quick response. Is there any way to make sure it's initialized exactly once?Limicoline
@Limicoline Yes there is. You can use Singleton Pattern to ensure single initialisation or if you are using any CDI environment (like Spring etc) they support this kind of functionality built-in.Register
my HibernateUtil looks kinda Singelton-ish...? Is my assumption right it's done correctly?Limicoline

© 2022 - 2024 — McMap. All rights reserved.