Hello, I'm try to use getCurrentSession() with JOTM in an un-managed environment. getCurrentSession() throws an exception unless I explicitly begin a transaction before getCurrentSession() is called.
(JTASessionContext)
txn = transactionManager.getTransaction();
if ( txn == null ) {
throw new HibernateException( "Unable to locate current JTA transaction" );
}
I understand this is the intended behavior, as in a managed environment the transaction demarcation would be declarative (e.g. the container would have started the transaction). My question is, in my unmanaged environment, what is the best way to begin the transaction when one doesn’t exist? I’m using a dynamic proxy to hide the setup of the transaction, so I just need to know the right way to create it. Currently I’m doing this:
SessionFactoryImpl si = (SessionFactoryImpl) HibernateUtil.getSessionFactory();
TransactionManager tm = si.getTransactionManager();
if( tm.getTransaction() == null ) {
tm.begin();
}
This seems incorrect because I have to cast to obtain the SessionFactoryImpl. Is there a better way? The behavior should be, if a transaction doesn’t exist, begin a new one, otherwise use the existing transaction.
The code above is hidden in the framework as a dynamic proxy. Here is the same code in the context of the proxy method.
// All methods that need transactions will go though this proxy
public Object invoke(Object proxy, Method method, Object[] args) throws
Throwable {
Object ret = null;
SessionFactoryImpl si = (SessionFactoryImpl) HibernateUtil.getSessionFactory();
TransactionManager tm = si.getTransactionManager();
if( tm.getTransaction() == null ) {
tm.begin();
}
Session s = HibernateUtil.getSessionFactory().getCurrentSession();
Transaction tx = null;
try {
tx = tm.getTransaction();
ret = method.invoke(obj, args); <-- the method that needs a transaction boundary
tx.commit();
...
}
Thanks!
|