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.  [ 11 posts ] 
Author Message
 Post subject: What might cause rollback() in hibernate2 to do nothing?
PostPosted: Tue May 22, 2007 12:59 am 
Newbie

Joined: Mon Sep 11, 2006 3:38 pm
Posts: 9
I've got a big inherited application, and lo and behold, rollback() and transactions don't work. I doubt anyone can solve the problem for me, but where can I at least look? How might these transactions get committed? I do something simple like:

Code:
object.setSomething("test " + new Date);
  mySession.rollback();


And yet the data gets committed. The rollback implementation is:

Code:

public abstract class AbstractHibernatePersister implements PersistenceManager {
....
        public void rollback() throws PersistenceException {
        logger.error("rollback()");
        Session session = this.getSession();
        if( session != null ) {
            try {
                session.connection().rollback();
                logger.error("session.connection().rollback() " + session.connection().getAutoCommit() + " isolation=" + session.connection().getTransactionIsolation());
            } catch( Exception e ) {
                throw new PersistenceException(e);
            }
        }
    }
...





And yes autoCommit is false, and the isolation level is 2. This is hibernate 2.1.4, on a xwork/webwork platform, with Java 1.4.2 and JDBC with Postgres 8.current as the database.

There is a mysterious comment in the code:
Code:
/**
     * Suppressing rollback functionality is required to allow centralized management of transaction state.  The
     * individual managers no longer control where the transaction boundaries are, but rather the system controls it
     * through interceptors.
     */

And the code I'm working with does seem to extend a lot of classes.

_________________
http://www.citycarshare.org/


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 22, 2007 9:19 am 
Senior
Senior

Joined: Thu May 17, 2007 2:31 am
Posts: 194
Location: Sri Lanka
Hi

try this

use
Code:
session.beginTransaction().rollback();

/*session.connection().rollback(); */




session.beginTransaction() will return a Transaction object which assosiated with session object.


Amila


Top
 Profile  
 
 Post subject: Nope
PostPosted: Tue May 22, 2007 10:42 am 
Newbie

Joined: Mon Sep 11, 2006 3:38 pm
Posts: 9
No rollback. The transaction is still persisted:
Quote:
session.connection().rollback();
logger.error("rollback() AutoCommit=" + session.connection().getAutoCommit() + " tisolation=" + session.connection().getTransactionIsolation() + " session=" + session );
session.beginTransaction().rollback(); // TODO: TEST

_________________
http://www.citycarshare.org/


Top
 Profile  
 
 Post subject:
PostPosted: Tue May 22, 2007 10:50 am 
Senior
Senior

Joined: Thu May 17, 2007 2:31 am
Posts: 194
Location: Sri Lanka
Hi

Don't use session.connection() method.

send code of AbstractHibernatePersister.



Amila


Top
 Profile  
 
 Post subject: Here's the code
PostPosted: Wed May 23, 2007 1:52 am 
Newbie

Joined: Mon Sep 11, 2006 3:38 pm
Posts: 9
Code:
public class HibernateFilter implements Filter {
    private static Logger logger = Logger.getLogger(HibernateFilter.class);

    DenaliSessionFactory sessionFactory;

    public void init(FilterConfig filterConfig) throws ServletException {
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        if (SetupStatus.isSetupComplete() == false) {
            filterChain.doFilter(request, response);
            return;
        }

        if (sessionFactory == null) {
            sessionFactory = DenaliSessionFactory.getInstance();
        }

        Session session = null;
        Transaction transaction = null;
        boolean success = true;
        try {
            session = sessionFactory.openSession();
            if (logger.isTraceEnabled()) {
                session = (Session) Proxy.newProxyInstance(this.getClass().getClassLoader(),
                        new Class[]{Session.class},
                        new LoggingProxy(session));
            }
            session.connection().setAutoCommit(false);
            transaction = session.beginTransaction();       // NEW!!!
            logger.error("Minted session. " + session + " Started transaction: " + transaction );
            HibernateSessionLocal.setSession(session);
            filterChain.doFilter(request, response);

        } catch (HibernateException e) {
            throw new ServletException(e);

        } catch (SQLException e) {
            throw new ServletException(e);

        } finally {
            if (session != null) {
                logger.error("Closing session " + session );
                logger.error("Transaction " + transaction.toString() );     // NEW!!
                // session.beginTransaction().rollback();
                try {
                    if (success) {
                        session.flush();
                        session.connection().commit();
                    } else {
                        session.connection().rollback();
                    }
                } catch (Exception e) {
                    logger.warn("problem closing Hibernate session ... " + e.getMessage(), e);
                }

                try {
                    session.close();
                } catch (HibernateException e) {
                    logger.warn("problem closing Hibernate session ... " + e.getMessage(), e);
                }
            }
            HibernateSessionLocal.setSession(null);
        }
    }

    public void destroy() {
    }
}

_________________
http://www.citycarshare.org/


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 23, 2007 6:35 am 
Senior
Senior

Joined: Thu May 17, 2007 2:31 am
Posts: 194
Location: Sri Lanka
Hi

I think your success variable is always true . You can yse transaction.commit() and transaction.rollback().


Amila


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 23, 2007 11:04 am 
Newbie

Joined: Mon Sep 11, 2006 3:38 pm
Posts: 9
Yes, the code is weird (inherited), and success is always true.
There's also no way to pass the transaction object through, so I have to depend on the session object.

The code seems to mix calls to session.connection() with calls to the session in a way that's unclear.

_________________
http://www.citycarshare.org/


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 23, 2007 11:56 am 
Newbie

Joined: Mon Sep 11, 2006 3:38 pm
Posts: 9
This code

Code:
session.beginTransaction().rollback();
logger.error("wasRolledBack " + transaction.wasRolledBack() +  " wasCommitted " + transaction.wasCommitted());
transaction.rollback();
logger.error("wasRolledBack " + transaction.wasRolledBack() +  " wasCommitted " + transaction.wasCommitted());


Returns:
Code:
wasRolledBack false wasCommitted false
wasRolledBack true wasCommitted false


But the transaction still gets commited if flush() is called, even though it has been rolled back. Is that normal?

_________________
http://www.citycarshare.org/


Top
 Profile  
 
 Post subject:
PostPosted: Wed May 23, 2007 12:45 pm 
Newbie

Joined: Mon Sep 11, 2006 3:38 pm
Posts: 9
And session.beginTransaction() returns a different object each time, despite the documentation that says it will attach to the current transaction:

Code:
Minted session. net.sf.hibernate.impl.SessionImpl@1e30857 Started transaction: net.sf.hibernate.transaction.JDBCTransaction@389922
session.beginTransaction()=net.sf.hibernate.transaction.JDBCTransaction@ed7f5c
Closing session net.sf.hibernate.impl.SessionImpl@1e30857 Transaction net.sf.hibernate.transaction.JDBCTransaction@389922

_________________
http://www.citycarshare.org/


Top
 Profile  
 
 Post subject:
PostPosted: Thu May 24, 2007 12:28 am 
Senior
Senior

Joined: Thu May 17, 2007 2:31 am
Posts: 194
Location: Sri Lanka
Hi

send code when you actually use session to save object. which might in servlet


Amila

(Don't forget to rate if helps)


Top
 Profile  
 
 Post subject: solved
PostPosted: Thu May 24, 2007 12:57 am 
Newbie

Joined: Mon Sep 11, 2006 3:38 pm
Posts: 9
Code:
import javax.servlet.*;

public class HibernateFilter implements Filter {
    private static Logger logger = Logger.getLogger(HibernateFilter.class);
    DenaliSessionFactory sessionFactory;

    public void init(FilterConfig filterConfig) throws ServletException {
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws ServletException, IOException {

        if (SetupStatus.isSetupComplete() == false) {
            filterChain.doFilter(request, response);
            return;
        }

        if (sessionFactory == null) {
            sessionFactory = DenaliSessionFactory.getInstance();
        }

        Session     session     = null;
        Transaction transaction = null;
        try {
            session     = sessionFactory.openSession();
            transaction = session.beginTransaction();
            logger.trace("Minted session " + session + " started transaction " + transaction );
            if (logger.isTraceEnabled()) {
                session = (Session) Proxy.newProxyInstance(this.getClass().getClassLoader(),
                        new Class[]{Session.class},
                        new LoggingProxy(session));
            }
            HibernateSessionLocal.setSession    (session);
            HibernateSessionLocal.setTransaction(transaction);

            // chain down, eventually doing an action
            filterChain.doFilter(request, response);

        } catch (HibernateException e) {
            throw new ServletException(e);
        } finally {
            if (session != null) {
                try {
                    logger.trace("Finally for session " + session + " transaction " + transaction + " or maybe transaction " + session.beginTransaction());
                    logger.trace("wasRolledBack " + transaction.wasRolledBack() +  " wasCommitted " + transaction.wasCommitted());
                    if( transaction.wasRolledBack() ) {
                        logger.error("transaction rollback()");
                        session.close();
                    } else {
                        logger.trace("transaction commit()");
                        transaction.commit();
                        session.flush();
                        session.close();
                    }

                } catch (Exception e) {
                    logger.error("severe problem closing Hibernate session ... " + e.getMessage(), e);
                }
            }
            HibernateSessionLocal.setSession(null);
        }
    }

    public void destroy() {
    }
}


I've pretty much solved it at this point. It appears that transaction.rollback() is not the final word on things as I'd assumed. I have to branch on the transaction.wasRolledBack() flag, and either flush() or just close().

_________________
http://www.citycarshare.org/


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 11 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.