[英]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
:
为什么要使用ThreadLocal
, Session#getCurrentSession()
方法为您处理该问题(尽管您似乎并未使用本地线程)。
在HibernateUtil.getCurrentSession()
,为什么会getCurrentSession()
和openSession()
? 首先,无需执行任何操作,如果没有session
与当前线程关联,则getCurrentSession()
将返回一个新session
。 其次,这两种方法是不同的,并且具有不同的语义(使用openSession()
时,您需要自己关闭session
),应该使用其中一种。
关于您的BaseAction
:
Session#beginTransaction()
之后clear()
会话。 如果您没有提交正在进行的交易,则将丢失所有未决的更改。 这真的是您想要的吗? PS:我会考虑使用“ 在视图中打开会话”模式来消除代码中的所有这些负担。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.