2015-10-20 80 views
0

我正在使用Hibernate 5.0.2.Final與數據源連接(在Tomcat 8.0.15上),並開始問我自己是否有必要關閉Session而且還需要SessionFactory?會話和工廠應該關閉嗎?

現在它看起來是這樣的:

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; 
} 
} 

我猶豫着:

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; 
    } 

從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> 

而且HibernateUtil中的一些細節有必要或不要在finally塊中調用此方法,而不是僅關閉會話:

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); 
    } 
} 

回答

2

你應該不是每次查詢關閉SessionFactory。您的SessionFactory應僅在每個應用程序中初始化一次。

hibernate documentation

這裏的主要合同是創建Session實例。通常, 應用程序具有一個SessionFactory實例,並且服務於客戶端請求的線程 從該工廠獲取Session實例。 SessionFactory的內部狀態是不可變的。一旦創建了這個內部狀態 被設置。該內部狀態包括關於對象/關係映射的元數據的所有 。

執行者必須是線程安全的。

+0

太好了,謝謝你的快速響應。有什麼方法可以確保它剛剛初始化一次? – Qohelet

+1

@Qohelet是的。您可以使用Singleton Pattern來確保單個初始化,或者如果您使用任何CDI環境(如Spring等),它們都支持這種內置的功能。 – bhdrkn

+0

我的HibernateUtil看起來有點像Singelton-ish ...?我的假設是正確的嗎? – Qohelet