HibernateUtil.java

  1. import javax.naming.InitialContext;  
  2. import javax.naming.NamingException;  
  3.  
  4. import org.apache.commons.logging.Log;  
  5. import org.apache.commons.logging.LogFactory;  
  6. import org.hibernate.Interceptor;  
  7. import org.hibernate.Session;  
  8. import org.hibernate.SessionFactory;  
  9. import org.hibernate.Transaction;  
  10. import org.hibernate.cfg.Configuration;  
  11. import org.hibernate.cfg.Environment;  
  12. import org.hibernate.transaction.CMTTransactionFactory;  
  13.  
  14. /**  
  15. * Hibernate 工具类 用于初始化Hibernate,并进行Session和Transaction的管理  
  16. */  
  17. public class HibernateUtil {  
  18.  
  19. private static Log log = LogFactory.getLog(HibernateUtil.class);  
  20.  
  21. private static final String INTERCEPTOR_CLASS = "hibernate.util.interceptor_class";  
  22.  
  23. private static Configuration configuration;  
  24.  
  25. private static SessionFactory sessionFactory;  
  26.  
  27. private static boolean useThreadLocal = true;  
  28.  
  29. // 保存Session对象实例的线程局部变量  
  30. private static ThreadLocal threadSession = new ThreadLocal();  
  31.  
  32. // 保存Transaction对象实例的线程局部变量  
  33. private static ThreadLocal threadTransaction = new ThreadLocal();  
  34.  
  35. static {  
  36. try {  
  37. // 创建Configuration对象  
  38. configuration = new Configuration();  
  39.  
  40. // 读取hibernate.properties或者hibernate.cfg.xml文件  
  41. configuration.configure();  
  42.  
  43. // 指定一个全局的用户子定义的拦截器  
  44. String interceptorName = configuration  
  45. .getProperty(INTERCEPTOR_CLASS);  
  46. if (interceptorName != null) {  
  47. Class interceptorClass = HibernateUtil.class.getClassLoader()  
  48. .loadClass(interceptorName);  
  49. Interceptor interceptor = (Interceptor) interceptorClass  
  50. .newInstance();  
  51. configuration.setInterceptor(interceptor);  
  52. }  
  53.  
  54. // 如果使用CMT,那么就不使用线程安全的Session和Transaction 
  55. if (CMTTransactionFactory.class  
  56. .getName()  
  57. .equals(  
  58. configuration  
  59. .getProperty(Environment.TRANSACTION_STRATEGY))) {  
  60. useThreadLocal = false;  
  61. }  
  62.  
  63. if (configuration.getProperty(Environment.SESSION_FACTORY_NAME) != null) {  
  64. // 绑定Hibernate到JNDI  
  65. configuration.buildSessionFactory();  
  66. else {  
  67. // 使用静态的变量  
  68. sessionFactory = configuration.buildSessionFactory();  
  69. }  
  70. } catch (Throwable ex) {  
  71. // 必须捕获Throwable,否则不能捕获NoClassDefFoundError异常以及它的子类错误  
  72. log.error("Building SessionFactory failed!", ex);  
  73. throw new ExceptionInInitializerError(ex);  
  74. }  
  75. }  
  76.  
  77. /**  
  78. * 返回全局的SessionFactory对象的实例  
  79. *   
  80. * @return SessionFactory  
  81. */  
  82. public static SessionFactory getSessionFactory() {  
  83. SessionFactory sf = null;  
  84. String sfName = configuration  
  85. .getProperty(Environment.SESSION_FACTORY_NAME);  
  86. if (sfName != null) {  
  87. log.debug("Looking up SessionFactory in JNDI.");  
  88. try {  
  89. sf = (SessionFactory) new InitialContext().lookup(sfName);  
  90. } catch (NamingException e) {  
  91. throw new RuntimeException(e);  
  92. }  
  93. else {  
  94. sf = sessionFactory;  
  95. }  
  96. if (sf == null) {  
  97. throw new IllegalStateException("SessionFactory not available.");  
  98. }  
  99. return sf;  
  100. }  
  101.  
  102. /**  
  103. * 重新构建SessionFactory对象的实例  
  104. *   
  105. */  
  106. public static void rebuildSessionFactory() {  
  107. log.debug("Using current Configuration for rebuild");  
  108. rebuildSessionFactory(configuration);  
  109. }  
  110.  
  111. /**  
  112. * 使用指定的Configuration对象重新构建SessionFactory对象的实例  
  113. *   
  114. * @param cfg  
  115. */  
  116. public static void rebuildSessionFactory(Configuration cfg) {  
  117. log.debug("Rebuilding the SessionFactory from given Configuration.");  
  118. synchronized (sessionFactory) {  
  119. if (sessionFactory != null && !sessionFactory.isClosed()) {  
  120. sessionFactory.close();  
  121. }  
  122. if (cfg.getProperty(Environment.SESSION_FACTORY_NAME) != null) {  
  123. cfg.buildSessionFactory();  
  124. else {  
  125. sessionFactory = cfg.buildSessionFactory();  
  126. }  
  127. configuration = cfg;  
  128. }  
  129. }  
  130.  
  131. /**  
  132. * 关闭当前SessionFactory并且释放所有资源  
  133. *   
  134. */  
  135. public static void shutdown() {  
  136. log.debug("Shutting down Hibernate.");  
  137. // 关闭缓冲和连接池  
  138. getSessionFactory().close();  
  139.  
  140. // 清除静态变量  
  141. configuration = null;  
  142. sessionFactory = null;  
  143.  
  144. // 清除本地进程变量  
  145. threadSession.set(null);  
  146. threadTransaction.set(null);  
  147. }  
  148.  
  149. /**  
  150. * 获得当前Session对象的实例  
  151. *   
  152. * @return Session  
  153. */  
  154. public static Session getCurrentSession() {  
  155. if (useThreadLocal) {  
  156. Session s = (Session) threadSession.get();  
  157. if (s == null) {  
  158. log.debug("Opening new Session for this thread.");  
  159. s = getSessionFactory().openSession();  
  160. threadSession.set(s);  
  161. }  
  162. return s;  
  163. else {  
  164. return getSessionFactory().getCurrentSession();  
  165. }  
  166. }  
  167.  
  168. /**  
  169. * 重新连接当前的Session  
  170. *   
  171. * @param session  
  172. */  
  173. public static void reconnect(Session session) {  
  174. if (useThreadLocal) {  
  175. log.debug("Reconnecting Session to this thrwad.");  
  176. session.reconnect();  
  177. threadSession.set(session);  
  178. else {  
  179. log  
  180. .error("Using CMT/JTA,intercepted not supported reconnect call.");  
  181. }  
  182. }  
  183.  
  184. /**  
  185. * 断开当前Session  
  186. *   
  187. * @return Session the disconnected Session  
  188. */  
  189. public static Session disconnectedSession() {  
  190. if (useThreadLocal) {  
  191. Transaction tx = (Transaction) threadTransaction.get();  
  192. if (tx != null && (!tx.wasCommitted() || !tx.wasRolledBack())) {  
  193. throw new IllegalStateException(  
  194. "Disconnecting Session but Transaction still open.");  
  195. }  
  196. Session session = getCurrentSession();  
  197. threadSession.set(null);  
  198. if (session.isConnected() && session.isOpen()) {  
  199. log.debug("Disconnecting Session from this thread.");  
  200. session.disconnect();  
  201. }  
  202. return session;  
  203. else {  
  204. log  
  205. .error("Using CMT/JTA,intercepted not supported disconnect call.");  
  206. return null;  
  207. }  
  208. }  
  209.  
  210. /**  
  211. * 关闭Session对象  
  212. *   
  213. */  
  214. public static void closeSession() {  
  215. if (useThreadLocal) {  
  216. Session s = (Session) threadSession.get();  
  217. threadSession.set(null);  
  218. Transaction tx = (Transaction) threadTransaction.get();  
  219. if (tx != null && (!tx.wasCommitted() || !tx.wasRolledBack())) {  
  220. throw new IllegalStateException(  
  221. "Closing Session but Transaction still open.");  
  222. }  
  223. if (s != null && s.isOpen()) {  
  224. log.debug("Closing Session of this thread.");  
  225. s.close();  
  226. }  
  227. else {  
  228. log.warn("Using CMT/JTA,intercepted superfluous close call.");  
  229. }  
  230. }  
  231.  
  232. /**  
  233. * 开始一个新的数据库事务  
  234. *   
  235. */  
  236. public static void beginTransaction() {  
  237. if (useThreadLocal) {  
  238. Transaction tx = (Transaction) threadTransaction.get();  
  239. if (tx == null) {  
  240. log.debug("Starting new database transaction in this thread.");  
  241. tx= getCurrentSession().beginTransaction();  
  242. threadTransaction.set(tx);  
  243. }  
  244.  
  245. else {  
  246. log.warn("Using CMT/JTA,intercepted superfluous tx begin call.");  
  247. }  
  248. }  
  249.  
  250. /**  
  251. * 提交数据库事务  
  252. *   
  253. */  
  254. public static void commitTransaction() {  
  255. if (useThreadLocal) {  
  256. try {  
  257. Transaction tx = (Transaction) threadTransaction.get();  
  258. if (tx != null && !tx.wasCommitted() && !tx.wasRolledBack()) {  
  259. log  
  260. .debug("Committing database transaction of this thread.");  
  261. tx.commit();  
  262. }  
  263. threadTransaction.set(null);  
  264. } catch (RuntimeException e) {  
  265. log.error(e);  
  266. rollbackTransaction();  
  267. throw e;  
  268. }  
  269. else {  
  270. log.warn("Using CMT/JTA,intercepted superfluous tx commit call.");  
  271. }  
  272. }  
  273.  
  274. /**  
  275. * 回滚数据库事务  
  276. *   
  277. */  
  278. public static void rollbackTransaction() {  
  279. if (useThreadLocal) {  
  280.  
  281. Transaction tx = (Transaction) threadTransaction.get();  
  282. try {  
  283. threadTransaction.set(null);  
  284. if (tx != null && !tx.wasCommitted() && !tx.wasRolledBack()) {  
  285. log  
  286. .debug("Trying to rollback database transaction of this thread.");  
  287. tx.rollback();  
  288. }  
  289. } catch (RuntimeException e) {  
  290. throw new RuntimeException(  
  291. "Migth swallow original cause,check Error log!", e);  
  292. } finally {  
  293. closeSession();  
  294. }  
  295. else {  
  296. log.warn("Using CMT/JTA,intercepted superfluous tx rollback call.");  
  297. }  
  298. }