Hibernate save() and transaction rollback

30,007

Solution 1

Check if your database supports a roll back i.e. if you're using InnoDB tables and not MyISAM (you can mix transactional and non-transactional tables but in most cases, you want all your tables to be InnoDB).

Solution 2

MySQL by default uses the MyIsam storage engine. As the MyISAM does not support transactions, insert, update and delete statements are directly written to the database. The commit and rollback statements are ignored.

In order to use transaction you need to change the storage engine of you tables. Use this command:

ALTER TABLE table_name ENGINE = InnoDB;

(note how ever, that the two storage engines are different and you need to test you're application if it still behaves as expected)

Share:
30,007
Mark
Author by

Mark

Updated on November 18, 2020

Comments

  • Mark
    Mark over 3 years

    In Hibernate when i save() an object in a transaction, and then i rollback it, the saved object still remains in the DB. It's strange because this issue doesn't happen with the update() or delete() method, just with save().

    Here is the code i'm using:

    DbEntity dbEntity = getDbEntity();
    HibernateUtil.beginTransaction();
    Session session = HibernateUtil.getCurrentSession();
    session.save(dbEntity);
    HibernateUtil.rollbackTransaction();
    

    And here is the HibernateUtil class (just the involved functions, i guarantee the getSessionFactory() method works well - there is an Interceptor handler, but it doesn't matter now):

    private static final ThreadLocal<Session> threadSession = new ThreadLocal<Session>();
    private static final ThreadLocal<Transaction> threadTransaction = new ThreadLocal<Transaction>();
    
    /**
    * Retrieves the current Session local to the thread.
    * <p/>
    * If no Session is open, opens a new Session for the running thread.
    *
    * @return Session
    */
    public static Session getCurrentSession()
        throws HibernateException {
        Session s = (Session) threadSession.get();
        try {
            if (s == null) {
                log.debug("Opening new Session for this thread.");
                if (getInterceptor() != null) {
                    log.debug("Using interceptor: " + getInterceptor().getClass());
                    s = getSessionFactory().openSession(getInterceptor());
                } else {
                    s = getSessionFactory().openSession();
                }
                threadSession.set(s);
            }
        } catch (HibernateException ex) {
            throw new HibernateException(ex);
        }
        return s;
    }
    
    /**
    * Start a new database transaction.
    */
    public static void beginTransaction()
        throws HibernateException {
        Transaction tx = (Transaction) threadTransaction.get();
        try {
            if (tx == null) {
                log.debug("Starting new database transaction in this thread.");
                tx = getCurrentSession().beginTransaction();
                threadTransaction.set(tx);
            }
        } catch (HibernateException ex) {
            throw new HibernateException(ex);
        }
    }
    
    /**
     * Rollback the database transaction.
     */
    public static void rollbackTransaction()
        throws HibernateException {
        Transaction tx = (Transaction) threadTransaction.get();
        try {
            threadTransaction.set(null);
            if ( tx != null && !tx.wasCommitted() && !tx.wasRolledBack() ) {
                log.debug("Tyring to rollback database transaction of this thread.");
                tx.rollback();
            }
        } catch (HibernateException ex) {
            throw new HibernateException(ex);
        } finally {
            closeSession();
        }
    }
    

    Thanks