请注意,在hibernate中SessionFactory是被设计成线程安全(Thread-safe)的,遗憾的是,Session却线程不安全。
这就意味着:有可能多个线程共享并操作同一个Session从而很容易使数据混乱。
解决的办法如下:(其实hibernate的文档中早已经提过了)
新建HibernateUtil类:
- import org.apache.commons.logging.Log;
- import org.apache.commons.logging.LogFactory;
- import org.hibernate.*;
- import org.hibernate.cfg.*;
- public class HibernateUtil {
- private static Log log = LogFactory.getLog(HibernateUtil.class);
- private static final SessionFactory sessionFactory;
- static {
- try {
- // Create the SessionFactory
- sessionFactory = new Configuration().configure()
- .buildSessionFactory();
- } catch (Throwable ex) {
- // Make sure you log the exception, as it might be swallowed
- log.error("Initial SessionFactory creation failed.", ex);
- throw new ExceptionInInitializerError(ex);
- }
- }
- public static final ThreadLocal session = new ThreadLocal();
- public static Session currentSession() {
- Session s = (Session) session.get();
- // Open a new Session, if this Thread has none yet
- if (s == null) {
- s = sessionFactory.openSession();
- session.set(s);
- }
- return s;
- }
- public static void closeSession() {
- Session s = (Session) session.get();
- if (s != null) {
- s.close();
- }
- session.set(null);
- }
- }
这样,在程序中可这样调用:
- Session session = HibernateUtil.currentSession();
- User user = (User) session.load(User.class, new Integer(1));
- System.out.println(user.getName());
- HibernateUtil.closeSession();
在web应用中,可以借由Filter来进行session管理。在需要session的时候开启session,在request结束之后关闭session。
HibernateSessionUtil.java
- import java.io.Serializable;
- import net.sf.hibernate.HibernateException;
- import net.sf.hibernate.Session;
- import net.sf.hibernate.SessionFactory;
- import net.sf.hibernate.Transaction;
- public class HibernateSessionUtil implements Serializable
- {
- public static final ThreadLocal tLocalsess = new ThreadLocal();
- public static final ThreadLocal tLocaltx = new ThreadLocal();
- /*
- * getting the thread-safe session for using
- */
- public static Session currentSession(){
- Session session = (Session) tLocalsess.get();
- //open a new one, if none can be found.
- try{
- if (session == null){
- session = openSession();
- tLocalsess.set(session);
- }
- }catch (HibernateException e){
- throw new InfrastructureException(e);
- }
- return session;
- }
- /*
- * closing the thread-safe session
- */
- public static void closeSession(){
- Session session = (Session) tLocalsess.get();
- tLocalsess.set(null);
- try{
- if (session != null && session.isOpen()){
- session.close();
- }
- }catch (HibernateException e){
- throw new InfrastructureException(e);
- }
- }
- /*
- * begin the transaction
- */
- public static void beginTransaction(){
- Transaction tx = (Transaction) tLocaltx.get();
- try{
- if (tx == null){
- tx = currentSession().beginTransaction();
- tLocaltx.set(tx);
- }
- }catch (HibernateException e){
- throw new InfrastructureException(e);
- }
- }
- /*
- * close the transaction
- */
- public static void commitTransaction(){
- Transaction tx = (Transaction) tLocaltx.get();
- try{
- if (tx != null && !tx.wasCommitted() && !tx.wasRolledBack())
- tx.commit();
- tLocaltx.set(null);
- }catch (HibernateException e){
- throw new InfrastructureException(e);
- }
- }
- /*
- * for rollbacking
- */
- public static void rollbackTransaction(){
- Transaction tx = (Transaction) tLocaltx.get();
- try{
- tLocaltx.set(null);
- if (tx != null && !tx.wasCommitted() && !tx.wasRolledBack()){
- tx.rollback();
- }
- }catch (HibernateException e){
- throw new InfrastructureException(e);
- }
- }
- private static Session openSession() throws HibernateException{
- return getSessionFactory().openSession();
- }
- private static SessionFactory getSessionFactory() throws HibernateException{
- return SingletonSessionFactory.getInstance();
- }
- }
filter中则:
- public class HibernateSessionCloser implements Filter{
- protected FilterConfig filterConfig = null;
- public void init(FilterConfig filterConfig)throws ServletException{
- this.filterConfig = filterConfig;
- }
-
- public void destroy(){
- this.filterConfig = null;
- }
- public void doFilter(ServletRequest request, ServletResponse response,
- FilterChain chain)
- throws IOException, ServletException {
- try{
- chain.doFilter(request, response);
- }
- finally{
- try{
- HibernateSessionUtil.commitTransaction();
- }catch (InfrastructureException e){
- HibernateSessionUtil.rollbackTransaction();
- }finally{
- HibernateSessionUtil.closeSession();
- }
- }
- }
- }
然后在操作数据库前加上
HibernateSessionUtil.beginTransaction();
HibernateSessionUtil.currentSession();//取得Session
ExtJS教程-
Hibernate教程-
Struts2 教程-
Lucene教程