-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 
Author Message
 Post subject: Exception in Transaction Rollback with EJB
PostPosted: Thu Aug 12, 2004 3:21 pm 
Newbie

Joined: Thu Aug 12, 2004 10:02 am
Posts: 8
Hibernate version:

Mapping documents:

Code between sessionFactory.openSession() and session.close():

Full stack trace of any exception that occurs:

Name and version of the database you are using:

Debug level Hibernate log excerpt:


When ever a runtime exception occurs after session.save(POJO), hibernate tries
to insert the data into the database eventhough it is "already marked for rollback" by Jboss.
We are using hibernate as persistence layer for our enterprise application which is the client
of stateless session beans.

The error in the jboss server.log is:

18:16:46,921 DEBUG [Printer] com.krcl.rap.object.AlmkAirline{airDesc=amma, airCd=amma}
18:16:46,937 DEBUG [SessionImpl] executing flush
18:16:46,937 DEBUG [EntityPersister] Inserting entity: [com.krcl.rap.object.AlmkAirline#amma]
18:16:46,937 DEBUG [BatcherImpl] about to open: 0 open PreparedStatements, 0 open ResultSets
18:16:46,953 INFO [TxConnectionManager] Could not enlist XAResource!
javax.transaction.RollbackException: Already marked for rollback
at org.jboss.tm.TransactionImpl.enlistResource(TransactionImpl.java:588)
at org.jboss.resource.connectionmanager.TxConnectionManager$TxConnectionEventListener.enlist(TxConnectionManager.java:455)
at org.jboss.resource.connectionmanager.TxConnectionManager.managedConnectionReconnected(TxConnectionManager.java:343)
at org.jboss.resource.connectionmanager.BaseConnectionManager2.allocateConnection(BaseConnectionManager2.java:483)
at org.jboss.resource.connectionmanager.BaseConnectionManager2$ConnectionManagerProxy.allocateConnection(BaseConnectionManager2.java:814)
at org.jboss.resource.adapter.jdbc.WrapperDataSource.getConnection(WrapperDataSource.java:102)
at net.sf.hibernate.connection.DatasourceConnectionProvider.getConnection(DatasourceConnectionProvider.java:59)
at net.sf.hibernate.impl.BatcherImpl.openConnection(BatcherImpl.java:278)
at net.sf.hibernate.impl.SessionImpl.connect(SessionImpl.java:3302)
at net.sf.hibernate.impl.SessionImpl.connection(SessionImpl.java:3282)
at net.sf.hibernate.impl.BatcherImpl.prepareStatement(BatcherImpl.java:61)
at net.sf.hibernate.impl.BatcherImpl.prepareStatement(BatcherImpl.java:56)
at net.sf.hibernate.impl.BatcherImpl.prepareBatchStatement(BatcherImpl.java:109)
at net.sf.hibernate.persister.EntityPersister.insert(EntityPersister.java:460)
at net.sf.hibernate.persister.EntityPersister.insert(EntityPersister.java:442)
at net.sf.hibernate.impl.ScheduledInsertion.execute(ScheduledInsertion.java:29)
at net.sf.hibernate.impl.SessionImpl.executeAll(SessionImpl.java:2414)
at net.sf.hibernate.impl.SessionImpl.execute(SessionImpl.java:2367)
at net.sf.hibernate.impl.SessionImpl.flush(SessionImpl.java:2236)
at com.krcl.rap.masters.HibernateUtil$SessionSynchronization.beforeCompletion(HibernateUtil.java:174)
at org.jboss.tm.TransactionImpl.doBeforeCompletion(TransactionImpl.java:1308)
at org.jboss.tm.TransactionImpl.rollback(TransactionImpl.java:456)
at org.jboss.ejb.plugins.TxInterceptorCMT.endTransaction(TxInterceptorCMT.java:390)
at org.jboss.ejb.plugins.TxInterceptorCMT.runWithTransactions(TxInterceptorCMT.java:277)
at org.jboss.ejb.plugins.TxInterceptorCMT.invoke(TxInterceptorCMT.java:128)
at org.jboss.ejb.plugins.SecurityInterceptor.invoke(SecurityInterceptor.java:118)
at org.jboss.ejb.plugins.LogInterceptor.invoke(LogInterceptor.java:191)
at org.jboss.ejb.plugins.ProxyFactoryFinderInterceptor.invoke(ProxyFactoryFinderInterceptor.java:122)
at org.jboss.ejb.StatelessSessionContainer.internalInvoke(StatelessSessionContainer.java:331)
at org.jboss.ejb.Container.invoke(Container.java:700)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at org.jboss.mx.capability.ReflectedMBeanDispatcher.invoke(ReflectedMBeanDispatcher.java:284)
at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:546)
at org.jboss.invocation.jrmp.server.JRMPInvoker.invoke(JRMPInvoker.java:367)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:261)
at sun.rmi.transport.Transport$1.run(Transport.java:148)
at java.security.AccessController.doPrivileged(Native Method)
at sun.rmi.transport.Transport.serviceCall(Transport.java:144)
at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:460)
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:701)
at java.lang.Thread.run(Thread.java:534)
18:16:47,000 INFO [TxConnectionManager] Could not enlist in transaction on entering meta-aware object!

The code in EJB which is responsible for the above exception is :



public void createTrainingCenter_h (TrainingMasterVO trainingVO) throws RemoteException, NamingException, HibRuntimeException, HibernateException
{

try {
SessionFactory sessionFactory = HibernateUtil.lookupSessionFactory();
Session session = HibernateUtil.getSession(sessionFactory);
AlmkAirline tCenter = new AlmkAirline();
tCenter.setAirCd(trainingVO.getCentreCode());
tCenter.setAirDesc(trainingVO.getCentreDescription());
session.save(tCenter);
if (true) {
ctx.setRollbackOnly();
throw new RemoteException();
}

} catch (NamingException ne) {
ne.printStackTrace();
throw ne;
} catch (HibRuntimeException he) {
he.printStackTrace();
throw he;
} catch (HibernateException e) {
e.printStackTrace();
throw e;
}
}

The HibernateUtil class is defined below:

import java.util.HashMap;
import java.util.Map;

import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.transaction.RollbackException;
import javax.transaction.Synchronization;
import javax.transaction.SystemException;
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;

import net.sf.hibernate.HibernateException;
import net.sf.hibernate.Session;
import net.sf.hibernate.SessionFactory;
import net.sf.hibernate.engine.SessionFactoryImplementor;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


/**
* Class allowing for reuse of Hibernate Session instances within a transaction
* transaction.
*/
public class HibernateUtil {

private static Log logger =
LogFactory.getLog(HibernateUtil.class);

private static ThreadLocal sessionSynchronizations = new ThreadLocal();

public static SessionFactory lookupSessionFactory() throws NamingException {
InitialContext initCtx = new InitialContext();
return (SessionFactory) initCtx.lookup("java:/hibernate/HibernateFactory");
}

/**
* Gets a session from the given session factory. If a session has already
* been asked for this session factory in the current JTA transaction, the
* same session is returned. Else, a new session is created.
* The returned session will automatically be flushed and closed at the end
* of the current JTA transaction.
* @param sessionFactory the factory from which to get the session
* @return a session associated with the current JTA transaction.
*/
public static Session getSession(SessionFactory sessionFactory) throws HibRuntimeException {
try {
Map map = getSessionSynchronizationMap();
Key key = new Key(sessionFactory, getCurrentTransaction(sessionFactory));
SessionSynchronization sync = (SessionSynchronization) map.get(key);
if (sync == null) {
Session session = sessionFactory.openSession();
sync = new SessionSynchronization(key, session);
map.put(key, sync);
getCurrentTransaction(sessionFactory).registerSynchronization(sync);
}
return sync.getSession();
}
catch(SystemException e) {
throw new HibRuntimeException(e);
}
catch(HibernateException e) {
throw new HibRuntimeException(e);
}
catch(RollbackException e) {
throw new HibRuntimeException(e);
}
}

/**
* Gets the thread local map storing the session synchronizations.
* The returned map contains Key instances as keys and SessionSynchronization
* instances as values
*/
private static Map getSessionSynchronizationMap() {
Map map = (Map) sessionSynchronizations.get();
if (map == null) {
map = new HashMap();
sessionSynchronizations.set(map);
}
return map;
}

/**
* Gets the current JTA transaction.
* @param sessionFactory the session factory allowing to get the current
* transaction
* @return the current JTA transaction
* @throws SystemException
*/
private static Transaction getCurrentTransaction(SessionFactory sessionFactory) throws SystemException {
SessionFactoryImplementor sessionFactoryImpl =
(SessionFactoryImplementor) sessionFactory;
TransactionManager txManager = sessionFactoryImpl.getTransactionManager();
return txManager.getTransaction();
}

/**
* Closes the given session and removes the session synchronization identified
* by the given key from its map.
*/
private static void closeSession(Key key, Session session) throws HibernateException {
getSessionSynchronizationMap().remove(key);
session.close();
}


/**
* A class combining a session factory and a JTA transaction. It's used as
* key in the map of session synchronizations.
*/
private static class Key {
private SessionFactory sessionFactory;
private Transaction transaction;

public Key(SessionFactory sessionFactory, Transaction transaction) {
this.sessionFactory = sessionFactory;
this.transaction = transaction;
}

public SessionFactory getSessionFactory() {
return sessionFactory;
}

public Transaction getTransaction() {
return transaction;
}

public boolean equals(Object o) {
if (o == this) {
return true;
}

if (o instanceof Key) {
Key k = (Key) o;
return ((k.transaction == this.transaction)
&& (k.sessionFactory == this.sessionFactory));
}
return false;
}

public int hashCode() {
return (37 * transaction.hashCode()) + sessionFactory.hashCode();
}
}

/**
* Class allowing to close a session at the end of a JTA transaction.
*/
private static class SessionSynchronization implements Synchronization {

private Key key;
private Session session;

public SessionSynchronization(Key key, Session session) {
this.key = key;
this.session = session;
}

/**
* @see javax.transaction.Synchronization#beforeCompletion()
*/
public void beforeCompletion() {
logger.debug("beforeCompletion called");
try {
session.flush();
closeSession(key, session);
this.session = null;
}
catch (HibernateException e) {
logger.error("impossible to flush or close the session", e);
//throw new HibRuntimeException(e);
}
}

/**
* @see javax.transaction.Synchronization#afterCompletion(int)
*/
public void afterCompletion(int status) {
logger.debug("afterCompletion called");
if (this.session != null) {
try {
closeSession(key, session);
this.session = null;
}
catch (HibernateException e) {
logger.warn("impossible to close the session", e);
}
}
}

public Session getSession() {
return session;
}
}
}

What goes wrong in my code? Can anybody suggest how transaction rollback is handled when
Hibernate is used with stateless session beans.

Thanks in Advance
Best regards
Amrit







_________________
amritkumar


Top
 Profile  
 
 Post subject:
PostPosted: Mon Aug 16, 2004 9:20 am 
Hibernate Team
Hibernate Team

Joined: Sun Sep 14, 2003 3:54 am
Posts: 7256
Location: Paris, France
If the tx is marked for rollback, the connexion (and thus the hibernate session) should not be used anymore unless you repopen a new tx. This more a JDBC/SQL design.

I usually stop using my hibernate session while rollbacking the tx.

_________________
Emmanuel


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 2 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.