package karan.modules.hibernatetry; import org.hibernate.*; import org.hibernate.cfg.*; import org.apache.log4j.*; /** * Basic Hibernate helper class, handles SessionFactory, Session and Transaction. *
* Uses a static initializer for the initial SessionFactory creation * and holds Session and Transactions in thread local variables. All * exceptions are wrapped in an unchecked InfrastructureException. * * Hibernate startup includes building a global SessionFactory object and to store it somewhere for easy access in application code. * A SessionFactory can open up new Session's. A Session represents a single-threaded unit of work, the SessionFactory is a thread-safe global object, instantiated once. * The HibernateUtil helper class takes care of startup and makes Session handling convenient. The so called ThreadLocal Session pattern is useful here, we keep the * current unit of work associated with the current thread. * * This class does not only produce the global SessionFactory in its static initializer (called once by the JVM when the class is loaded), but also has a ThreadLocal * variable to hold the Session for the current thread. No matter when you call HibernateUtil.currentSession(), it will always return the same Hibernate unit of work * in the same thread. A call to HibernateUtil.closeSession() ends the unit of work currently associated with the thread. * * This class is not necessary if you deploy Hibernate in a J2EE application server: a Session will be automatically bound to the current JTA transaction and you can * look up the SessionFactory through JNDI. If you use JBoss AS, Hibernate can be deployed as a managed system service and will automatically bind the SessionFactory to * a JNDI name. * * @author christian@hibernate.org */ public class HibernateUtil { private static Logger log = Logger.getLogger(HibernateUtil.class); private static Configuration configuration; private static SessionFactory sessionFactory; private static final ThreadLocal threadSession = new ThreadLocal(); private static final ThreadLocal threadTransaction = new ThreadLocal(); // Create the initial SessionFactory from the default configuration files static { try { // Replace with Configuration() if you don't use annotations configuration = new Configuration(); sessionFactory = configuration.configure().buildSessionFactory(); // We could also let Hibernate bind it to JNDI: // configuration.configure().buildSessionFactory() } catch (Throwable ex) { // We have to catch Throwable, otherwise we will miss // NoClassDefFoundError and other subclasses of Error log.error("Building SessionFactory failed.", ex); throw new ExceptionInInitializerError(ex); } } /** * Returns the SessionFactory used for this static class. * * @return SessionFactory */ public static SessionFactory getSessionFactory() { /* Instead of a static variable, use JNDI: SessionFactory sessions = null; try { javax.naming.Context ctx = new javax.naming.InitialContext(); String jndiName = "java:hibernate/HibernateFactory"; sessions = (SessionFactory)ctx.lookup(jndiName); } catch (javax.naming.NamingException ex) { throw new InfrastructureException(ex); } return sessions; */ return sessionFactory; } /** * Returns the original Hibernate configuration. * * @return Configuration */ public static Configuration getConfiguration() { return configuration; } /** * Rebuild the SessionFactory with the static Configuration. * */ public static void rebuildSessionFactory() throws InfrastructureException { /*synchronized (sessionFactory) { try { sessionFactory = getConfiguration().buildSessionFactory(); } catch (Exception ex) { throw new InfrastructureException(ex); } }*/ rebuildSessionFactory(configuration); // this single line was the original code } /** * Rebuild the SessionFactory with the given Hibernate Configuration. * * @param cfg */ public static void rebuildSessionFactory(Configuration cfg) throws InfrastructureException { synchronized(sessionFactory) { if (!sessionFactory.isClosed()) sessionFactory.close(); try { sessionFactory = cfg.buildSessionFactory(); configuration = cfg; } catch(Exception ex) { throw new InfrastructureException(ex); } } } /** * Retrieves the current Session local to the thread. *
* If no Session is open, opens a new Session for the running thread. * * @return Session */ public static Session getSession() throws InfrastructureException { Session s = (Session) threadSession.get(); try { if (s == null) { log.debug("Opening new Session for this thread."); /* if (getInterceptor() != null) { log.debug("Using interceptor: " + getInterceptor().getClass()); s = getSessionFactory().openSession(getInterceptor()); } else { */ s = getSessionFactory().openSession(); //} threadSession.set(s); } } catch (HibernateException ex) { throw new InfrastructureException(ex); } return s; } /** * Closes the Session local to the thread. */ public static void closeSession() throws InfrastructureException { try { Session s = (Session) threadSession.get(); threadSession.set(null); if (s != null && s.isOpen()) { log.debug("Closing Session of this thread."); s.close(); } } catch (HibernateException ex) { throw new InfrastructureException(ex); } } /** * Start a new database transaction. */ public static void beginTransaction() throws InfrastructureException { Transaction tx = (Transaction) threadTransaction.get(); try { if (tx == null) { log.debug("Starting new database transaction in this thread."); tx = getSession().beginTransaction(); threadTransaction.set(tx); } } catch (HibernateException ex) { throw new InfrastructureException(ex); } } /** * Commit the database transaction. */ public static void commitTransaction() throws InfrastructureException { Transaction tx = (Transaction) threadTransaction.get(); try { if ( tx != null && !tx.wasCommitted() && !tx.wasRolledBack() ) { log.debug("Committing database transaction of this thread."); tx.commit(); } threadTransaction.set(null); } catch (RuntimeException ex) { log.error(ex); rollbackTransaction(); throw new InfrastructureException(ex); } } /** * Rollback the database transaction. */ public static void rollbackTransaction() throws InfrastructureException { Transaction tx = (Transaction) threadTransaction.get(); try { threadTransaction.set(null); if ( tx != null && !tx.wasCommitted() && !tx.wasRolledBack() ) { log.debug("Tyring to rollback database transaction of this thread."); tx.rollback(); } } catch (RuntimeException ex) { throw new InfrastructureException("Might swallow original cause, check ERROR log!", ex); } finally { closeSession(); } } /** * Reconnects a Hibernate Session to the current Thread. * * @param session The Hibernate Session to be reconnected. */ public static void reconnect(Session session) throws InfrastructureException { try { session.reconnect(); threadSession.set(session); } catch (HibernateException ex) { throw new InfrastructureException(ex); } } /** * Disconnect and return Session from current Thread. * * @return Session the disconnected Session */ public static Session disconnectSession() throws InfrastructureException { Session session = getSession(); try { threadSession.set(null); if (session.isConnected() && session.isOpen()) session.disconnect(); } catch (HibernateException ex) { throw new InfrastructureException(ex); } return session; } /** * Register a Hibernate interceptor with the current SessionFactory. ** Every Session opened is opened with this interceptor after * registration. Has no effect if the current Session of the * thread is already open, effective on next close()/getSession(). */ public static void registerInterceptorAndRebuild(Interceptor interceptor) { configuration.setInterceptor(interceptor); rebuildSessionFactory(); } public static Interceptor getInterceptor() { return configuration.getInterceptor(); } }