【发布时间】:2010-09-28 19:37:40
【问题描述】:
我正在开发一个 web 应用程序,但在 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();
有没有办法避免上面的异常?
【问题讨论】:
-
我不明白你为什么要在交易结束后触摸它。
-
@Tony 好像是“应用”事务。
-
@Pascal Thivent 是对的,我会看看他的答案。