Hello,
Would it be possible to have HibernateUtil written in such a way that
it could be used both under CMT (Container-Managed-Transctions) and
without?
HibernateUtil is used by DAOs and people might want to use DAO
in CMT or in standalone apps (so they will commit transaction in their code).
I see that there is no call to sessionFactory.getCurrentSession() in current
HibernateUtil. AFAIK this is the method which has to be used under CMT
together with something like
Code:
<property name="transaction.manager_lookup_class">org.hibernate.transaction.JBossTransactionManagerLookup</property>
<property name="transaction.factory.class">org.hibernate.transaction.CMTTransactionFactory</property>
in hibernate-config.xml
DAOs call HibernateUtil.getSession() to get the session, and with CMT
it should return current Session and create a new only if it doesn't exit.
I believe that both DAOs code and HibernateUtil code should be written
in such way that it is same whether it is used in CMT or client
manages the transaction.
Thanks,
--MG
PS: Here is HibernateUtil I'm using (but it is far from perfect)
Code:
import javax.naming.InitialContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
private static Log log = LogFactory.getLog(HibernateUtil.class);
private static final SessionFactory sessionFactory;
private static final boolean SessionFactoryFromJNDI = false;
private static final String HIBERNATE_CONFIG = "hibernate.cfg.xml";
private static final String HIBERNATE_JBOSS_CONFIG = "/META-INF/hibernate-jboss.cfg.xml";
private static boolean useCMT = true;
static {
try {
// Create the SessionFactory
if (SessionFactoryFromJNDI)
sessionFactory = (SessionFactory) new InitialContext()
.lookup("SessionFactoryJNDI");
else {
String configName = HIBERNATE_JBOSS_CONFIG;
String standalone = System.getenv("HIBERNATE_STANDALONE");
if ((standalone != null) && (standalone.equalsIgnoreCase("YES"))) {
configName = HIBERNATE_CONFIG;
useCMT = false;
System.err.println("HIBERNATE_STANDALONE=" + standalone);
}
Configuration config = new Configuration().configure(configName);
sessionFactory = config.buildSessionFactory();
}
} catch (Throwable ex) {
// Make sure the exception is logged, as it might be swallowed
ex.printStackTrace(System.err);
log.error("Initial SessionFactory creation failed.", ex);
log.error(ex.getStackTrace());
throw new ExceptionInInitializerError(ex);
}
}
public static final ThreadLocal<Session> session = new ThreadLocal<Session>();
public static Session currentSession() {
Session s = null;
if (useCMT) {
s = sessionFactory.getCurrentSession();
if (s == null) {
s = sessionFactory.openSession();
}
}
else {
s = (Session) session.get();
// Open a new Session, if this Thread has none yet
if (s == null) {
s = sessionFactory.openSession();
session.set(s);
}
}
return s;
}
public static void closeSession() {
if (session != null) {
Session s = (Session) session.get();
if (s != null)
s.close();
session.set(null);
}
}
}