HibernateUtil 工具类

来源:互联网 发布:流量发短信软件 编辑:程序博客网 时间:2024/04/30 02:25
  1. public class HibernateUtil
  2. {
  3.     private static Log log = LogFactory.getLog(HibernateUtil.class);
  4.     private static final String INTERCEPTOR_CLASS = "hibernate.util.interceptor_class";
  5.     private static Configuration configuration;
  6.     private static SessionFactory sessionFactory;
  7.     private static ThreadLocal threadSession = new ThreadLocal();
  8.     private static ThreadLocal threadTransaction = new ThreadLocal();
  9.     private static boolean useThreadLocal = true;
  10.     static {
  11.         // Create the initial SessionFactory from the default configuration files
  12.         try {
  13.             // Replace with Configuration() if you don't use annotations or JDK 5.0
  14.             //configuration = new AnnotationConfiguration();
  15.             configuration = new Configuration();
  16.             // Read not only hibernate.properties, but also hibernate.cfg.xml
  17.             configuration.configure();
  18.             // Assign a global, user-defined interceptor with no-arg constructor
  19.             String interceptorName = configuration.getProperty(INTERCEPTOR_CLASS);
  20.             if (interceptorName != null) {
  21.                 Class interceptorClass =
  22.                         HibernateUtil.class.getClassLoader().loadClass(interceptorName);
  23.                 Interceptor interceptor = (Interceptor)interceptorClass.newInstance();
  24.                 configuration.setInterceptor(interceptor);
  25.             }
  26.             // Disable ThreadLocal Session/Transaction handling if CMT is used
  27.             if (org.hibernate.transaction.CMTTransactionFactory.class.getName()
  28.                  .equals( configuration.getProperty(Environment.TRANSACTION_STRATEGY) ) )
  29.                 useThreadLocal = false;
  30.             if (configuration.getProperty(Environment.SESSION_FACTORY_NAME) != null) {
  31.                 // Let Hibernate bind it to JNDI
  32.                 configuration.buildSessionFactory();
  33.             } else {
  34.                 // or use static variable handling
  35.                 sessionFactory = configuration.buildSessionFactory();
  36.             }
  37.         } catch (Throwable ex) {
  38.             // We have to catch Throwable, otherwise we will miss
  39.             // NoClassDefFoundError and other subclasses of Error
  40.             log.error("Building SessionFactory failed.", ex);
  41.             throw new ExceptionInInitializerError(ex);
  42.         }
  43.     }
  44.     /**
  45.      * Returns the original Hibernate configuration.
  46.      *
  47.      * @return Configuration
  48.      */
  49.     public static Configuration getConfiguration() {
  50.         return configuration;
  51.     }
  52.     /**
  53.      * Returns the global SessionFactory.
  54.      *
  55.      * @return SessionFactory
  56.      */
  57.     public static SessionFactory getSessionFactory() {
  58.         SessionFactory sf = null;
  59.         String sfName = configuration.getProperty(Environment.SESSION_FACTORY_NAME);
  60.         if ( sfName != null) {
  61.             log.debug("Looking up SessionFactory in JNDI.");
  62.             try {
  63.                 sf = (SessionFactory) new InitialContext().lookup(sfName);
  64.             } catch (NamingException ex) {
  65.                 throw new RuntimeException(ex);
  66.             }
  67.         } else {
  68.             sf = sessionFactory;
  69.         }
  70.         if (sf == null)
  71.             throw new IllegalStateException("SessionFactory not available.");
  72.         return sf;
  73.     }
  74.     /**
  75.      * Closes the current SessionFactory and releases all resources.
  76.      * <p>
  77.      * The only other method that can be called on HibernateUtil
  78.      * after this one is rebuildSessionFactory(Configuration).
  79.      */
  80.     public static void shutdown() {
  81.         log.debug("Shutting down Hibernate.");
  82.         // Close caches and connection pools
  83.         getSessionFactory().close();
  84.         // Clear static variables
  85.         configuration = null;
  86.         sessionFactory = null;
  87.         // Clear ThreadLocal variables
  88.         threadSession.set(null);
  89.         threadTransaction.set(null);
  90.     }
  91.     /**
  92.      * Rebuild the SessionFactory with the static Configuration.
  93.      * <p>
  94.      * This method also closes the old SessionFactory before, if still open.
  95.      * Note that this method should only be used with static SessionFactory
  96.      * management, not with JNDI or any other external registry.
  97.      */
  98.      public static void rebuildSessionFactory() {
  99.         log.debug("Using current Configuration for rebuild.");
  100.         rebuildSessionFactory(configuration);
  101.      }
  102.     /**
  103.      * Rebuild the SessionFactory with the given Hibernate Configuration.
  104.      * <p>
  105.      * HibernateUtil does not configure() the given Configuration object,
  106.      * it directly calls buildSessionFactory(). This method also closes
  107.      * the old SessionFactory before, if still open.
  108.      *
  109.      * @param cfg
  110.      */
  111.      public static void rebuildSessionFactory(Configuration cfg) {
  112.         log.debug("Rebuilding the SessionFactory from given Configuration.");
  113.         synchronized(sessionFactory) {
  114.             if (sessionFactory != null && !sessionFactory.isClosed())
  115.                 sessionFactory.close();
  116.             if (cfg.getProperty(Environment.SESSION_FACTORY_NAME) != null)
  117.                 cfg.buildSessionFactory();
  118.             else
  119.                 sessionFactory = cfg.buildSessionFactory();
  120.             configuration = cfg;
  121.         }
  122.      }
  123.     /**
  124.      * Retrieves the current Session local to the thread.
  125.      * <p/>
  126.      * If no Session is open, opens a new Session for the running thread.
  127.      * If CMT is used, returns the Session bound to the current JTA
  128.      * container transaction. Most other operations on this class will
  129.      * then be no-ops or not supported, the container handles Session
  130.      * and Transaction boundaries, ThreadLocals are not used.
  131.      *
  132.      * @return Session
  133.      */
  134.     public static Session getCurrentSession() {
  135.         if (useThreadLocal) {
  136.             Session s = (Session) threadSession.get();
  137.             if (s == null) {
  138.                 log.debug("Opening new Session for this thread.");
  139.                 s = getSessionFactory().openSession();
  140.                 threadSession.set(s);
  141.             }
  142.             return s;
  143.         } else {
  144.             return getSessionFactory().getCurrentSession();
  145.         }
  146.     }
  147.     /**
  148.      * Closes the Session local to the thread.
  149.      * <p>
  150.      * Is a no-op (with warning) if called in a CMT environment. Should be
  151.      * used in non-managed environments with resource local transactions, or
  152.      * with EJBs and bean-managed transactions.
  153.      */
  154.     public static void closeSession() {
  155.         if (useThreadLocal) {
  156.             Session s = (Session) threadSession.get();
  157.             threadSession.set(null);
  158.             Transaction tx = (Transaction) threadTransaction.get();
  159.             if (tx != null && (!tx.wasCommitted() || !tx.wasRolledBack()) )
  160.                 throw new IllegalStateException("Closing Session but Transaction still open!");
  161.             if (s != null && s.isOpen()) {
  162.                 log.debug("Closing Session of this thread.");
  163.                 s.close();
  164.             }
  165.         } else {
  166.             log.warn("Using CMT/JTA, intercepted superfluous close call.");
  167.         }
  168.     }
  169.     /**
  170.      * Start a new database transaction.
  171.      * <p>
  172.      * Is a no-op (with warning) if called in a CMT environment. Should be
  173.      * used in non-managed environments with resource local transactions, or
  174.      * with EJBs and bean-managed transactions. In both cases, it will either
  175.      * start a new transaction or join the existing ThreadLocal or JTA
  176.      * transaction.
  177.      */
  178.     public static void beginTransaction() {
  179.         if (useThreadLocal) {
  180.             Transaction tx = (Transaction) threadTransaction.get();
  181.             if (tx == null) {
  182.                 log.debug("Starting new database transaction in this thread.");
  183.                 tx = getCurrentSession().beginTransaction();
  184.                 threadTransaction.set(tx);
  185.             }
  186.         } else {
  187.             log.warn("Using CMT/JTA, intercepted superfluous tx begin call.");
  188.         }
  189.     }
  190.     /**
  191.      * Commit the database transaction.
  192.      * <p>
  193.      * Is a no-op (with warning) if called in a CMT environment. Should be
  194.      * used in non-managed environments with resource local transactions, or
  195.      * with EJBs and bean-managed transactions. It will commit the
  196.      * ThreadLocal or BMT/JTA transaction.
  197.      */
  198.     public static void commitTransaction() {
  199.         if (useThreadLocal) {
  200.             Transaction tx = (Transaction) threadTransaction.get();
  201.             try {
  202.                 if ( tx != null && !tx.wasCommitted()
  203.                                 && !tx.wasRolledBack() ) {
  204.                     log.debug("Committing database transaction of this thread.");
  205.                     tx.commit();
  206.                 }
  207.                 threadTransaction.set(null);
  208.             } catch (RuntimeException ex) {
  209.                 log.error(ex);
  210.                 rollbackTransaction();
  211.                 throw ex;
  212.             }
  213.         } else {
  214.             log.warn("Using CMT/JTA, intercepted superfluous tx commit call.");
  215.         }
  216.     }
  217.     /**
  218.      * Rollback the database transaction.
  219.      * <p>
  220.      * Is a no-op (with warning) if called in a CMT environment. Should be
  221.      * used in non-managed environments with resource local transactions, or
  222.      * with EJBs and bean-managed transactions. It will rollback the
  223.      * resource local or BMT/JTA transaction.
  224.      */
  225.     public static void rollbackTransaction() {
  226.         if (useThreadLocal) {
  227.             Transaction tx = (Transaction) threadTransaction.get();
  228.             try {
  229.                 threadTransaction.set(null);
  230.                 if ( tx != null && !tx.wasCommitted() && !tx.wasRolledBack() ) {
  231.                     log.debug("Tyring to rollback database transaction of this thread.");
  232.                     tx.rollback();
  233.                     log.debug("Database transaction rolled back.");
  234.                 }
  235.             } catch (RuntimeException ex) {
  236.                 throw new RuntimeException("Might swallow original cause, check ERROR log!", ex);
  237.             } finally {
  238.                 closeSession();
  239.             }
  240.         } else {
  241.             log.warn("Using CMT/JTA, intercepted superfluous tx rollback call.");
  242.         }
  243.     }
  244.     /**
  245.      * Reconnects a Hibernate Session to the current Thread.
  246.      * <p>
  247.      * Unsupported in a CMT environment.
  248.      *
  249.      * @param session The Hibernate Session to be reconnected.
  250.      */
  251.     public static void reconnect(Session session) {
  252.         if (useThreadLocal) {
  253.             log.debug("Reconnecting Session to this thread.");
  254.             session.reconnect();
  255.             threadSession.set(session);
  256.         } else {
  257.             log.error("Using CMT/JTA, intercepted not supported reconnect call.");
  258.         }
  259.     }
  260.     /**
  261.      * Disconnect and return Session from current Thread.
  262.      *
  263.      * @return Session the disconnected Session
  264.      */
  265.     public static Session disconnectSession() {
  266.         if (useThreadLocal) {
  267.             Transaction tx = (Transaction) threadTransaction.get();
  268.             if (tx != null && (!tx.wasCommitted() || !tx.wasRolledBack()) )
  269.                 throw new IllegalStateException("Disconnecting Session but Transaction still open!");
  270.             Session session = getCurrentSession();
  271.             threadSession.set(null);
  272.             if (session.isConnected() && session.isOpen()) {
  273.                 log.debug("Disconnecting Session from this thread.");
  274.                 session.disconnect();
  275.             }
  276.             return session;
  277.         } else {
  278.             log.error("Using CMT/JTA, intercepted not supported disconnect call.");
  279.             return null;
  280.         }
  281.     }
  282.     /**
  283.      * Register a Hibernate interceptor with the current SessionFactory.
  284.      * <p>
  285.      * Every Session opened is opened with this interceptor after
  286.      * registration. Has no effect if the current Session of the
  287.      * thread is already open, effective on next close()/getCurrentSession().
  288.      * <p>
  289.      * Attention: This method effectively restarts Hibernate. If you
  290.      * need an interceptor active on static startup of HibernateUtil, set
  291.      * the <tt>hibernateutil.interceptor</tt> system property to its
  292.      * fully qualified class name.
  293.      */
  294.     public static void registerInterceptorAndRebuild(Interceptor interceptor) {
  295.         log.debug("Setting new global Hibernate interceptor and restarting.");
  296.         configuration.setInterceptor(interceptor);
  297.         rebuildSessionFactory();
  298.     }
  299.     public static Interceptor getInterceptor() {
  300.         return configuration.getInterceptor();
  301.     }
  302. }
原创粉丝点击