//HibernateSessionFactory.java
package com.yigoware.hibernate;import net.sf.hibernate.HibernateException;
import net.sf.hibernate.Session;
import net.sf.hibernate.cfg.Configuration;/**
 * Configures and provides access to Hibernate sessions, tied to the current
 * thread of execution. Follows the Thread Local Session pattern, see
 * {@link http://hibernate.org/42.html}.
 */
public class HibernateSessionFactory { /**
 * Location of hibernate.cfg.xml file. NOTICE: Location should be on the
 * classpath as Hibernate uses #resourceAsStream style lookup for its
 * configuration file. That is place the config file in a Java package - the
 * default location is the default Java package. <br>
 * <br>
 * Examples: <br>
 * <code>CONFIG_FILE_LOCATION = "/hibernate.conf.xml". 
 * CONFIG_FILE_LOCATION = "/com/foo/bar/myhiberstuff.conf.xml".</code>
 */
private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml"; /** Holds a single instance of Session */
private static final ThreadLocal threadLocal = new ThreadLocal(); /** The single instance of hibernate configuration */
private static final Configuration config = new Configuration(); /** The single instance of hibernate SessionFactory */
private static net.sf.hibernate.SessionFactory sessionFactory; /**
 * Returns the ThreadLocal Session instance. Lazy initialize the
 * <code>SessionFactory</code> if needed.
 * 
 * @return Session
 * @throws HibernateException
 */
public static Session currentSession() throws HibernateException {
Session session = (Session) threadLocal.get(); if (session == null) {
if (sessionFactory == null) {
try {
config.configure(CONFIG_FILE_LOCATION);
sessionFactory = config.buildSessionFactory();
} catch (Exception e) {
System.err
.println("%%%% Error Creating SessionFactory %%%%");
e.printStackTrace();
}
}
session = sessionFactory.openSession();
threadLocal.set(session);
} return session;
} /**
 * Close the single hibernate session instance.
 * 
 * @throws HibernateException
 */
public static void closeSession() throws HibernateException {
Session session = (Session) threadLocal.get();
threadLocal.set(null); if (session != null) {
session.close();
}
} /**
 * Default constructor.
 */
private HibernateSessionFactory() {
}}

解决方案 »

  1.   

    //注释太多了,重新贴
    //HibernateSessionFactory.java
    package com.yigoware.hibernate;import net.sf.hibernate.HibernateException;
    import net.sf.hibernate.Session;
    import net.sf.hibernate.cfg.Configuration;public class HibernateSessionFactory { private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml"; private static final ThreadLocal threadLocal = new ThreadLocal(); private static final Configuration config = new Configuration(); private static net.sf.hibernate.SessionFactory sessionFactory; public static Session currentSession() throws HibernateException {
    Session session = (Session) threadLocal.get(); if (session == null) {
    if (sessionFactory == null) {
    try {
    config.configure(CONFIG_FILE_LOCATION);
    sessionFactory = config.buildSessionFactory();
    } catch (Exception e) {
    System.err
    .println("%%%% Error Creating SessionFactory %%%%");
    e.printStackTrace();
    }
    }
    session = sessionFactory.openSession();
    threadLocal.set(session);
    } return session;
    } public static void closeSession() throws HibernateException {
    Session session = (Session) threadLocal.get();
    threadLocal.set(null); if (session != null) {
    session.close();
    }
    } private HibernateSessionFactory() {
    }}
      

  2.   

    //操作数据库的UserDAO.java
    //这里面的session.close()只能关闭才行.
    /*
     * Created on 2005-6-22
     *
     * TODO To change the template for this generated file go to
     * Window - Preferences - Java - Code Style - Code Templates
     */
    package com.yigoware.dao;import java.util.List;import net.sf.hibernate.HibernateException;
    import net.sf.hibernate.Query;
    import net.sf.hibernate.Session;
    import net.sf.hibernate.Transaction;import com.yigoware.hibernate.HibernateSessionFactory;
    import com.yigoware.model.User;/**
     * @author Administrator
     *  
     */
    public class UserDAO { public UserDAO() { } public static void main(String[] args) { } /**
     * 根据用户帐号查询用户(只返回一个)
     * 
     * @param account
     * @return
     * @throws Exception
     * @throws HibernateException
     */
    public User loadUserByAccount(String account) throws Exception {
    Session session = null;
    List users = null;
    try {
    session = HibernateSessionFactory.currentSession();
    Query query = session
    .createQuery("from User u where u.account = :account");
    query.setString("account", account);
    // System.out.println("account=" + account);
    users = query.list();
    } catch (HibernateException e) {
    e.printStackTrace();
    throw e;
    } finally {
    // session.close();
    }
    if (users.size() > 0)
    return (User) users.get(0);
    else
    return null;
    } /**
     * 新增保存用户的方法
     * 
     * @param user
     * @throws Exception
     */
    public void addUser(User user) throws Exception {
    Transaction tx = null;
    Session session = null;
    try {
    session = HibernateSessionFactory.currentSession();
    tx = session.beginTransaction();
    session.save(user);
    tx.commit();
    } catch (HibernateException e) {
    if (tx != null) {
    tx.rollback();
    }
    e.printStackTrace();
    throw e;
    } finally {
    // session.close();
    }
    }}
      

  3.   

    你分析一下HibernateSessionFactory 就知道了啊,你的关闭是这样的:session.close()
    应该是调用HibernateSessionFactory 的closeSession来关闭。
    为什么呢?
    那是因为session.close()之后,但session不为null,而下次你用的HibernateSessionFactory 的currentSession来取得session,显然这个session已经关闭了,而你的代码里面是:
    if (session == null) {...}才会重新open一个session的,所以返回的是你关闭了的session。
    都用HibernateSessionFactory 来管理你的session就没有问题了
      

  4.   

    那请问我是不是就不应该执行session.close()了?
    或者说执行HibernateSessionFactory.closeSession()?
      

  5.   

    HibernateSessionFactory是一个采用了singleton模式的类,session始终只有一个
    所以你用HibernateSessionFactory.closeSession()关就可以了,不关也不要紧。
      

  6.   

    恩,调通了,再问一下session不关的后果是什么?
      

  7.   

    public static void closeSession() throws HibernateException {
    Session session = (Session) threadLocal.get();
    threadLocal.set(null); if (session != null) {
    session.close();
    }
    }
    threadLocal.set(null); 这一句我不明白 为什么要set一个null啊