请注意,在hibernate中SessionFactory是被设计成线程安全(Thread-safe)的,遗憾的是,Session却线程不安全。
这就意味着:有可能多个线程共享并操作同一个Session从而很容易使数据混乱。
解决的办法如下:(其实hibernate的文档中早已经提过了)
新建HibernateUtil类:
1.import org.apache.commons.logging.Log;<br />2.import org.apache.commons.logging.LogFactory;<br />3.import org.hibernate.*;<br />4.import org.hibernate.cfg.*;<br />5.<br />6.public class HibernateUtil {<br />7. private static Log log = LogFactory.getLog(HibernateUtil.class);<br />8. private static final SessionFactory sessionFactory;<br />9.10. static {<br />11. try {<br />12. // Create the SessionFactory13. sessionFactory = new Configuration().configure()<br />14. .buildSessionFactory();<br />15. } catch (Throwable ex) {<br />16. // Make sure you log the exception, as it might be swallowed17. log.error("Initial SessionFactory creation failed.", ex);<br />18. throw new ExceptionInInitializerError(ex);<br />19. }<br />20. }<br />21.22. public static final ThreadLocal session = new ThreadLocal();<br />23.24. public static Session currentSession() {<br />25. Session s = (Session) session.get();<br />26.27. // Open a new Session, if this Thread has none yet28. if (s == null) {<br />29. s = sessionFactory.openSession();<br />30. session.set(s);<br />31. }<br />32.33. return s;<br />34. }<br />35.36. public static void closeSession() {<br />37. Session s = (Session) session.get();<br />38.39. if (s != null) {<br />40. s.close();<br />41. }<br />42.43. session.set(null);<br />44. }<br />45.}
这样,在程序中可这样调用:
1.Session session = HibernateUtil.currentSession();<br />2.User user = (User) session.load(User.class, new Integer(1));<br />3.System.out.println(user.getName());<br />4.HibernateUtil.closeSession();
在web应用中,可以借由Filter来进行session管理。在需要session的时候开启session,在request结束之后关闭session。
HibernateSessionUtil.java
1.import java.io.Serializable;<br />2.<br />3.import net.sf.hibernate.HibernateException;<br />4.import net.sf.hibernate.Session;<br />5.import net.sf.hibernate.SessionFactory;<br />6.import net.sf.hibernate.Transaction;<br />7.8.public class HibernateSessionUtil implements Serializable<br />9.{<br />10. public static final ThreadLocal tLocalsess = new ThreadLocal();<br />11.12. public static final ThreadLocal tLocaltx = new ThreadLocal();<br />13.14. /*<br />15. * getting the thread-safe session for using<br />16. */17. public static Session currentSession(){<br />18. Session session = (Session) tLocalsess.get();<br />19.20. //open a new one, if none can be found.21. try{<br />22. if (session == null){<br />23. session = openSession();<br />24. tLocalsess.set(session);<br />25. }<br />26. }catch (HibernateException e){<br />27. throw new InfrastructureException(e);<br />28. }<br />29. return session;<br />30. }<br />31.32. /*<br />33. * closing the thread-safe session<br />34. */35. public static void closeSession(){<br />36.37. Session session = (Session) tLocalsess.get();<br />38. tLocalsess.set(null);<br />39. try{<br />40. if (session != null && session.isOpen()){<br />41. session.close();<br />42. }<br />43.44. }catch (HibernateException e){<br />45. throw new InfrastructureException(e);<br />46. }<br />47. }<br />48.49. /*<br />50. * begin the transaction<br />51. */52. public static void beginTransaction(){<br />53. Transaction tx = (Transaction) tLocaltx.get();<br />54. try{<br />55. if (tx == null){<br />56. tx = currentSession().beginTransaction();<br />57. tLocaltx.set(tx);<br />58. }<br />59. }catch (HibernateException e){<br />60. throw new InfrastructureException(e);<br />61. }<br />62. }<br />63.64. /*<br />65. * close the transaction<br />66. */67. public static void commitTransaction(){<br />68. Transaction tx = (Transaction) tLocaltx.get();<br />69. try{<br />70. if (tx != null && !tx.wasCommitted() && !tx.wasRolledBack())<br />71. tx.commit();<br />72. tLocaltx.set(null);<br />73. }catch (HibernateException e){<br />74. throw new InfrastructureException(e);<br />75. }<br />76. }<br />77.78. /*<br />79. * for rollbacking<br />80. */81. public static void rollbackTransaction(){<br />82. Transaction tx = (Transaction) tLocaltx.get();<br />83. try{<br />84. tLocaltx.set(null);<br />85. if (tx != null && !tx.wasCommitted() && !tx.wasRolledBack()){<br />86. tx.rollback();<br />87. }<br />88. }catch (HibernateException e){<br />89. throw new InfrastructureException(e);<br />90. }<br />91. }<br />92.93. private static Session openSession() throws HibernateException{<br />94. return getSessionFactory().openSession();<br />95. }<br />96.97. private static SessionFactory getSessionFactory() throws HibernateException{<br />98. return SingletonSessionFactory.getInstance();<br />99. }<br />100.}
filter中则:
1.public class HibernateSessionCloser implements Filter{<br />2.<br />3. protected FilterConfig filterConfig = null;<br />4.5. public void init(FilterConfig filterConfig)throws ServletException{<br />6. this.filterConfig = filterConfig;<br />7. }<br />8. <br />9. public void destroy(){<br />10. this.filterConfig = null;<br />11. } <br />12.13. public void doFilter(ServletRequest request, ServletResponse response,<br />14. FilterChain chain)<br />15. throws IOException, ServletException {<br />16. try{<br />17. chain.doFilter(request, response);<br />18. }<br />19. finally{<br />20. try{<br />21. HibernateSessionUtil.commitTransaction();<br />22. }catch (InfrastructureException e){<br />23. HibernateSessionUtil.rollbackTransaction();<br />24. }finally{<br />25. HibernateSessionUtil.closeSession();<br />26. } <br />27. }<br />28.29. }<br />30.}
然后在操作数据库前加上
HibernateSessionUtil.beginTransaction();
HibernateSessionUtil.currentSession();//取得Session
未经一番寒彻骨,焉得梅花扑鼻香