繁体   English   中英

休眠连接问题

[英]Hibernate connection problems

我正在开发一个Webapp,Hibernate抛出异常后出现连接错误:

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

每当发生异常后,每次尝试访问数据库时,都会给我这个异常。

现在,如果我的应用程序编码正确,则Hibernate不应引发错误,但是如果与数据库的连接发生了某些情况,我不希望我的应用程序因该错误而卡住。

这是我的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();

有办法避免上述异常吗?

每当发生异常后,每次尝试访问数据库时,都会给我这个异常。

我不确定确切的情况。 无论如何,在发生异常之后,您应该回滚事务,关闭会话并重新开始。 话虽如此,我对您的代码有一些评论。

关于您的HibernateUtil

  • 为什么要使用ThreadLocalSession#getCurrentSession()方法为您处理该问题(尽管您似乎并未使用本地线程)。

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

关于您的BaseAction

  • 我想知道为什么您在Session#beginTransaction()之后clear()会话。 如果您没有提交正在进行的交易,则将丢失所有未决的更改。 这真的是您想要的吗?

PS:我会考虑使用“ 在视图中打开会话”模式来消除代码中的所有这些负担。

资源资源

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM