Hibernate connection problems
I'm working on a webapp and I have connection errors after Hibernate throws exceptions :
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: No operations allowed after connection closed.
It gave me this exception each time I try to access my db after an exception occured.
I now Hibernate's not supposed to throw errors if my application is well coded but if something happens with the connection to the db, I don't want my application to be stuck with this er开发者_JAVA技巧ror.
Here's my HibernateUtil class :
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();
}
}
Here's my BaseAction class where initialization and closing of sessions is set :
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();
}
}
Here's an example of an action:
Transaction transaction = new Transaction(user, Transaction.Type.REGISTRATION, new HashSet(domains));
initHibSession();
hib_session.save(transaction);
closeHibSession();
transaction_id = transaction.getId();
Is there a way to avoid the exception above ?
It gave me this exception each time I try to access my db after an exception occurred.
I'm not sure to understand the exact condition. Anyway, after an exception, you should rollback the transaction, close the session and start over. That being said, I have some remarks about your code.
About your HibernateUtil
:
why do you have a
ThreadLocal
, theSession#getCurrentSession()
method handle that for you (you don't seem to use the thread local though).in
HibernateUtil.getCurrentSession()
, why do you mess withgetCurrentSession()
andopenSession()
? Firstly, there is no need to do what you do,getCurrentSession()
will return a newsession
if nosession
is associated to the current thread. Secondly, both approaches are different and have different semantics (you need to close thesession
yourself when usingopenSession()
), you should use one or the other.
About your BaseAction
:
- I wonder why you
clear()
the session afterSession#beginTransaction()
. In case you didn't committed an ongoing transaction, you'll loose all the pending changes. Is this really what you want?
PS: I would consider using the Open Session in View pattern to remove all this burden from your code.
Resources
- Sessions and transactions
- Open Session in View
精彩评论