We have tried to different HibernateSessionFactory implementations.
This is the first:
Code:
public class HibernateSessionFactory {
private static final Logger logger = Logger.getLogger(HibernateSessionFactory.class);
private SessionFactory sessionFactory;
private static HibernateSessionFactory _instance = null;
private static int counter = 0;
/**
* Session is a thread local so that each thread has its own copy
*/
public static final ThreadLocal session = new ThreadLocal();
/**
* Hidden constructor
*/
private HibernateSessionFactory() {
super();
try {
// Create the SessionFactory
//
sessionFactory = new Configuration().configure().buildSessionFactory();
} catch (HibernateException ex) {
// something went wrong. Rethrow and catch
//
logger.fatal(ErrorCodes.getString(ErrorCodes.DB_ERROR_SESSION_CREATE), ex);
throw new RuntimeException(ErrorCodes.getString(ErrorCodes.DB_ERROR_SESSION_CREATE), ex);
}
}
/**
* Returnt the only instance of this session factory
*
* @return Session factory
*/
public static HibernateSessionFactory getInstance() {
if (_instance == null) {
_instance = new HibernateSessionFactory();
counter += 1;
return _instance;
} else {
return _instance;
}
}
/**
* Obtain a hibernate session
*
* @return A valid a Hibernate session
* @throws HibernateException
*/
public Session getSession() throws HibernateException {
// try to get a valid session
//
Session s = (Session) session.get();
// Open a new Session, if this Thread has none yet
//
if (s == null) {
// lets get a new session
//
s = sessionFactory.openSession();
session.set(s);
}
// return an active session
//
return s;
}
/**
* Disconnect and close a session
*
* @throws HibernateException
*/
public void closeSession() throws HibernateException {
// extract the local session
//
Session s = (Session) session.get();
session.set(null);
if (s != null) {
// notify the session that the transaction completed, so we no
// longer own the old locks. (Also we should release cache softlocks.)
// may be called multiple times during the transaction completion process.
// calling disconnect on the session has the effect of calling
// afterTransactionComplete(true);
//
s.disconnect();
// close the session
//
s.close();
}
}
}
This is the current one, similar to that from the docs:
Code:
public class HibernateSessionFactory {
private static final Logger logger = Logger.getLogger(HibernateSessionFactory.class);
private static SessionFactory sessionFactory;
/**
* Session is a thread local so that each thread has its own copy
*/
public static final ThreadLocal session = new ThreadLocal();
static {
try {
// Create the SessionFactory
sessionFactory = new Configuration().configure().buildSessionFactory();
} catch (Throwable ex) {
logger.error("Initial SessionFactory creation failed.", ex);
throw new ExceptionInInitializerError(ex);
}
}
/**
* Obtain a hibernate session
*
* @return A valid a Hibernate session
* @throws HibernateException
*/
public static Session getSession() throws HibernateException {
// try to get a valid session
//
Session s = (Session) session.get();
// Open a new Session, if this Thread has none yet
//
if (s == null) {
// lets get a new session
//
s = sessionFactory.openSession();
session.set(s);
}
// return an active session
//
return s;
}
/**
* Disconnect and close a session
*
* @throws HibernateException
*/
public static void closeSession() throws HibernateException {
// extract the local session
//
Session s = (Session) session.get();
if (s != null) {
// Completely clear the session. Evict all loaded instances
// and cancel all pending saves, updates and deletions.
// Do not close open iterators or instances of
// ScrollableResults
//
s.clear();
// notify the session that the transaction completed, so we no
// longer own the old locks. (Also we should release cache softlocks.)
// may be called multiple times during the transaction completion process.
// calling disconnect on the session has the effect of calling
// afterTransactionComplete(true);
//
s.disconnect();
// close the session
//
s.close();
}
session.set(null);
}
}
We have found that with our own implementation memory usage would creep up over time and not come down, yet this wasn't the case with the 2nd implementation. Obviously there are differences - most notably the static methods.
Can anyone make any comments on which method is better and why?
rgds,
Rilux