package cn.hxex.message.dao; import java.util.List; import cn.hxex.message.model.Message; publicinterface IMessageDAO ...{ publicvoid saveMessage( Message message ); publicvoid updateMessage( Message message ); public List getMessages( ); publicvoid deleteMessage( String id, String userId ); public Message getMessage( String id ); }
IUserDAO
package cn.hxex.message.dao; import cn.hxex.message.model.User; publicinterface IUserDAO ...{ publicvoid saveUser( User user ); public User getUser( String username ); public User getUserById( String id ); }
package cn.hxex.message.util; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; publicclass HibernateFilter implements Filter ...{ privatestatic Log log = LogFactory.getLog(HibernateFilter.class); publicvoid init(FilterConfig filterConfig) throws ServletException ...{ log.info("Servlet filter init, now opening/closing a Session for each request."); } publicvoid doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException ...{ // There is actually no explicit "opening" of a Session, the // first call to HibernateUtil.beginTransaction() in control // logic (e.g. use case controller/event handler, or even a // DAO factory) will get a fresh Session. try ...{ HibernateUtil.beginTransaction(); request.setCharacterEncoding( "gb2312" ); chain.doFilter(request, response); // Commit any pending database transaction. HibernateUtil.commitTransaction(); } catch (ServletException ex) ...{ log.debug("Rolling back the database transaction."); HibernateUtil.rollbackTransaction(); // Also closes the Session // Just rollback and let others handle the exception, e.g. for display throw ex; } catch (IOException ex) ...{ log.debug("Rolling back the database transaction."); HibernateUtil.rollbackTransaction(); // Also closes the Session // Just rollback and let others handle the exception, e.g. for display throw ex; } finally ...{ // No matter what happens, close the Session. HibernateUtil.closeSession(); } } publicvoid destroy() ...{} }
HibernateUtil
package cn.hxex.message.util; import javax.naming.InitialContext; import javax.naming.NamingException; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hibernate.Interceptor; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import org.hibernate.cfg.Environment; publicclass HibernateUtil ...{ privatestatic Log log = LogFactory.getLog(HibernateUtil.class); privatestaticfinal String INTERCEPTOR_CLASS ="hibernate.util.interceptor_class"; privatestatic Configuration configuration; privatestatic SessionFactory sessionFactory; privatestatic ThreadLocal threadSession =new ThreadLocal(); privatestatic ThreadLocal threadTransaction =new ThreadLocal(); privatestaticboolean useThreadLocal =true; static...{ // Create the initial SessionFactory from the default configuration files try...{ // Replace with Configuration() if you don't use annotations or JDK 5.0 //configuration = new AnnotationConfiguration(); configuration =new Configuration(); // Read not only hibernate.properties, but also hibernate.cfg.xml configuration.configure(); // Assign a global, user-defined interceptor with no-arg constructor String interceptorName = configuration.getProperty(INTERCEPTOR_CLASS); if (interceptorName !=null) ...{ Class interceptorClass = HibernateUtil.class.getClassLoader().loadClass(interceptorName); Interceptor interceptor = (Interceptor)interceptorClass.newInstance(); configuration.setInterceptor(interceptor); } // Disable ThreadLocal Session/Transaction handling if CMT is used if (org.hibernate.transaction.CMTTransactionFactory.class.getName() .equals( configuration.getProperty(Environment.TRANSACTION_STRATEGY) ) ) useThreadLocal =false; if (configuration.getProperty(Environment.SESSION_FACTORY_NAME) !=null) ...{ // Let Hibernate bind it to JNDI configuration.buildSessionFactory(); }else...{ // or use static variable handling sessionFactory = configuration.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); thrownew ExceptionInInitializerError(ex); } } /** *//** * Returns the original Hibernate configuration. * * @return Configuration */ publicstatic Configuration getConfiguration() ...{ return configuration; } /** *//** * Returns the global SessionFactory. * * @return SessionFactory */ publicstatic SessionFactory getSessionFactory() ...{ SessionFactory sf =null; String sfName = configuration.getProperty(Environment.SESSION_FACTORY_NAME); if ( sfName !=null) ...{ log.debug("Looking up SessionFactory in JNDI."); try...{ sf = (SessionFactory) new InitialContext().lookup(sfName); }catch (NamingException ex) ...{ thrownew RuntimeException(ex); } }else...{ sf = sessionFactory; } if (sf ==null) thrownew IllegalStateException("SessionFactory not available."); return sf; } /** *//** * Closes the current SessionFactory and releases all resources. * <p> * The only other method that can be called on HibernateUtil * after this one is rebuildSessionFactory(Configuration). */ publicstaticvoid shutdown() ...{ log.debug("Shutting down Hibernate."); // Close caches and connection pools getSessionFactory().close(); // Clear static variables configuration =null; sessionFactory =null; // Clear ThreadLocal variables threadSession.set(null); threadTransaction.set(null); } /** *//** * Rebuild the SessionFactory with the static Configuration. * <p> * This method also closes the old SessionFactory before, if still open. * Note that this method should only be used with static SessionFactory * management, not with JNDI or any other external registry. */ publicstaticvoid rebuildSessionFactory() ...{ log.debug("Using current Configuration for rebuild."); rebuildSessionFactory(configuration); } /** *//** * Rebuild the SessionFactory with the given Hibernate Configuration. * <p> * HibernateUtil does not configure() the given Configuration object, * it directly calls buildSessionFactory(). This method also closes * the old SessionFactory before, if still open. * * @param cfg */ publicstaticvoid rebuildSessionFactory(Configuration cfg) ...{ log.debug("Rebuilding the SessionFactory from given Configuration."); synchronized(sessionFactory) ...{ if (sessionFactory !=null&&!sessionFactory.isClosed()) sessionFactory.close(); if (cfg.getProperty(Environment.SESSION_FACTORY_NAME) !=null) cfg.buildSessionFactory(); else sessionFactory = cfg.buildSessionFactory(); configuration = cfg; } } /** *//** * Retrieves the current Session local to the thread. * <p/> * If no Session is open, opens a new Session for the running thread. * If CMT is used, returns the Session bound to the current JTA * container transaction. Most other operations on this class will * then be no-ops or not supported, the container handles Session * and Transaction boundaries, ThreadLocals are not used. * * @return Session */ publicstatic Session getCurrentSession() ...{ if (useThreadLocal) ...{ Session s = (Session) threadSession.get(); if (s ==null) ...{ log.debug("Opening new Session for this thread."); s = getSessionFactory().openSession(); threadSession.set(s); } return s; }else...{ return getSessionFactory().getCurrentSession(); } } /** *//** * Closes the Session local to the thread. * <p> * Is a no-op (with warning) if called in a CMT environment. Should be * used in non-managed environments with resource local transactions, or * with EJBs and bean-managed transactions. */ publicstaticvoid closeSession() ...{ if (useThreadLocal) ...{ Session s = (Session) threadSession.get(); threadSession.set(null); Transaction tx = (Transaction) threadTransaction.get(); if (tx !=null&& (!tx.wasCommitted() ||!tx.wasRolledBack()) ) thrownew IllegalStateException("Closing Session but Transaction still open!"); if (s !=null&& s.isOpen()) ...{ log.debug("Closing Session of this thread."); s.close(); } }else...{ log.warn("Using CMT/JTA, intercepted superfluous close call."); } } /** *//** * Start a new database transaction. * <p> * Is a no-op (with warning) if called in a CMT environment. Should be * used in non-managed environments with resource local transactions, or * with EJBs and bean-managed transactions. In both cases, it will either * start a new transaction or join the existing ThreadLocal or JTA * transaction. */ publicstaticvoid beginTransaction() ...{ if (useThreadLocal) ...{ Transaction tx = (Transaction) threadTransaction.get(); if (tx ==null) ...{ log.debug("Starting new database transaction in this thread."); tx = getCurrentSession().beginTransaction(); threadTransaction.set(tx); } }else...{ log.warn("Using CMT/JTA, intercepted superfluous tx begin call."); } } /** *//** * Commit the database transaction. * <p> * Is a no-op (with warning) if called in a CMT environment. Should be * used in non-managed environments with resource local transactions, or * with EJBs and bean-managed transactions. It will commit the * ThreadLocal or BMT/JTA transaction. */ publicstaticvoid commitTransaction() ...{ if (useThreadLocal) ...{ 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 ex; } }else...{ log.warn("Using CMT/JTA, intercepted superfluous tx commit call."); } } /** *//** * Rollback the database transaction. * <p> * Is a no-op (with warning) if called in a CMT environment. Should be * used in non-managed environments with resource local transactions, or * with EJBs and bean-managed transactions. It will rollback the * resource local or BMT/JTA transaction. */ publicstaticvoid rollbackTransaction() ...{ if (useThreadLocal) ...{ 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(); log.debug("Database transaction rolled back."); } }catch (RuntimeException ex) ...{ thrownew RuntimeException("Might swallow original cause, check ERROR log!", ex); }finally...{ closeSession(); } }else...{ log.warn("Using CMT/JTA, intercepted superfluous tx rollback call."); } } /** *//** * Reconnects a Hibernate Session to the current Thread. * <p> * Unsupported in a CMT environment. * * @param session The Hibernate Session to be reconnected. */ publicstaticvoid reconnect(Session session) ...{ if (useThreadLocal) ...{ log.debug("Reconnecting Session to this thread."); session.reconnect(); threadSession.set(session); }else...{ log.error("Using CMT/JTA, intercepted not supported reconnect call."); } } /** *//** * Disconnect and return Session from current Thread. * * @return Session the disconnected Session */ publicstatic Session disconnectSession() ...{ if (useThreadLocal) ...{ Transaction tx = (Transaction) threadTransaction.get(); if (tx !=null&& (!tx.wasCommitted() ||!tx.wasRolledBack()) ) thrownew IllegalStateException("Disconnecting Session but Transaction still open!"); Session session = getCurrentSession(); threadSession.set(null); if (session.isConnected() && session.isOpen()) ...{ log.debug("Disconnecting Session from this thread."); session.disconnect(); } return session; }else...{ log.error("Using CMT/JTA, intercepted not supported disconnect call."); returnnull; } } /** *//** * Register a Hibernate interceptor with the current SessionFactory. * <p> * 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()/getCurrentSession(). * <p> * Attention: This method effectively restarts Hibernate. If you * need an interceptor active on static startup of HibernateUtil, set * the <tt>hibernateutil.interceptor</tt> system property to its * fully qualified class name. */ publicstaticvoid registerInterceptorAndRebuild(Interceptor interceptor) ...{ log.debug("Setting new global Hibernate interceptor and restarting."); configuration.setInterceptor(interceptor); rebuildSessionFactory(); } publicstatic Interceptor getInterceptor() ...{ return configuration.getInterceptor(); } }