Hibernate连接问题

时间:2010-09-28 19:37:41

标签: java hibernate

我正在开发一个webapp,并且在Hibernate抛出异常后我遇到了连接错误:

com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.

每次在发生异常后尝试访问我的数据库时,它都给了我这个例外。

我现在Hibernate不应该抛出错误,如果我的应用程序编码良好但是如果与db的连接发生了某些事情,我不希望我的应用程序遇到这个错误。

这是我的HibernateUtil类:

public class HibernateUtil {
  private static Logger log = Logger.getLogger(HibernateUtil.class);
  private static org.hibernate.SessionFactory sessionFactory;
  private static String confFile = "hibernate-test.properties";
  private static final ThreadLocal<Session> threadSession = new ThreadLocal<Session>();

  private HibernateUtil() {

  }

  public static void buildSessionFactory(){
    Configuration configuration = new Configuration();
    synchronized(HibernateUtil.class){
      if(sessionFactory == null){
        try {
          Properties properties = new Properties();
          properties.load(HibernateUtil.class.getClassLoader().getResourceAsStream(confFile));
          configuration.setProperties(properties);
        } catch (Exception e) {
          log.fatal("cannot load the specified hibernate properties file: " + confFile);
          throw new RuntimeException("cannot load the specified hibernate properties file : " + confFile, e);
        }
        sessionFactory = configuration.configure().buildSessionFactory();
      }

      HibernatePBEEncryptorRegistry registry = HibernatePBEEncryptorRegistry.getInstance();

      if(registry.getPBEStringEncryptor("strongHibernateStringEncryptor") == null) {
        StandardPBEStringEncryptor strongEncryptor = new StandardPBEStringEncryptor();
        strongEncryptor.setAlgorithm("PBEWithMD5AndDES"); // not really needed as it is the default
        strongEncryptor.setPassword("aStrongPassword");
        registry.registerPBEStringEncryptor("strongHibernateStringEncryptor", strongEncryptor);
      }
    }
  }

  public static SessionFactory getSessionFactory() {
    if(sessionFactory == null){
      buildSessionFactory();
    }
    return sessionFactory;
  }

  public static Session getCurrentSession(){
    if(!getSessionFactory().getCurrentSession().isOpen())
      getSessionFactory().openSession();
    return getSessionFactory().getCurrentSession();
  }
}

这是我的BaseAction类,其中设置了会话的初始化和关闭:

public class BaseAction extends ActionSupport {

  public Session hib_session;

  public void initHibSession() {
    hib_session = HibernateUtil.getCurrentSession();
    hib_session.beginTransaction();
    hib_session.clear();
  }

  public void closeHibSession() {
    hib_session.getTransaction().commit();
  }
}

以下是一个动作示例:

Transaction transaction = new Transaction(user, Transaction.Type.REGISTRATION, new HashSet(domains));

initHibSession();
hib_session.save(transaction);
closeHibSession();
transaction_id = transaction.getId();

有没有办法避免上面的例外?

1 个答案:

答案 0 :(得分:1)

  

每次我发生异常后尝试访问我的数据库时,它都给了我这个例外。

我不确定了解具体情况。无论如何,在异常之后,您应该回滚事务,关闭会话并重新开始。话虽这么说,我对你的代码有一些评论。

关于HibernateUtil

  • 为什么你有一个ThreadLocalSession#getCurrentSession()方法处理对象(你似乎没有使用本地线程)。

  • HibernateUtil.getCurrentSession()中,为什么会混淆getCurrentSession()openSession()?首先,您无需执行操作,如果没有session与当前线程关联,getCurrentSession()将返回新的session。其次,两种方法都不同,并且具有不同的语义(您需要在使用openSession()时自己关闭session),您应该使用其中一种。

关于BaseAction

PS:我会考虑使用Sessions and transactions模式从代码中消除所有这些负担。

资源