Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Transaction not successfully started (while tx.commit() is surrounded by a if condition)

Tags:

java

hibernate

First time that I ran into this error I've surrounded my tx.commit() with a if condition but am not sure why I am still receiving this error.

Struts Problem Report

Struts has detected an unhandled exception:
Messages:   
Transaction not successfully started
File:   org/hibernate/engine/transaction/spi/AbstractTransactionImpl.java
Line number:    200
Stacktraces
org.hibernate.TransactionException: Transaction not successfully started

    org.hibernate.engine.transaction.spi.AbstractTransactionImpl.rollback(AbstractTransactionImpl.java:200)

After a product has been selected by user, in my main function I will call two functions as following.

First function to retrieve the object of selected product. Second function to check if selected user has the product therefore it returns true if client has the product otherwise returns false;

Function 1

  ....

    Product pro = new Product();
    final Session session = HibernateUtil.getSession();
    try {
        final Transaction tx = session.beginTransaction();
        try {

            pro = (Product) session.get(Product.class, id);

            if (!tx.wasCommitted()) {    
                     tx.commit();
            }
        } catch (Exception e) {
            tx.rollback();
            e.printStackTrace();
        }
    } finally {
        HibernateUtil.closeSession();
    }
   .....

Function 2

 .....
 final Session session = HibernateUtil.getSession();
        try {
            final Transaction tx = session.beginTransaction();
            try {
                User user = (User) session.get(User.class, id);

                if (!tx.wasCommitted()) {    
                       tx.commit();
                }

                if(client.hasProduct(proId)){
                         return client.getProduct(proId);
                }
                return false;
            } catch (Exception e) {
                tx.rollback();                 <<<Error is on this line
                e.printStackTrace();
            }
        } finally {
            HibernateUtil.closeSession();
        }
  ....        
like image 911
J888 Avatar asked Oct 21 '22 20:10

J888


1 Answers

Take a look at Transaction.isActive() method. You can wrap call to rollback() method with condition, checking whether transaction is still active. And the second, I'd prefer the following code:

final Session session = HibernateUtil.getSession();
try {
    final Transaction tx = session.beginTransaction();
    // do things
    tx.commit();
} finally {
    if (tx.isActive()) {
        try {
            tx.rollback();
        } catch (Exception e) {
            logger.log("Error rolling back transaction", e);
        }
    }
    try {
        session.close();
    } catch (Exception e) {
        logger.log("Error closing session", e);
    }
}

Of course, code in the finally section better to wrap into public static method and just call it in every finally.

BTW, why are you doing something outside tranaction? I usually commit after all things get done, to achieve a better consistency and avoid LazyInitializationException.

like image 142
Alexey Andreev Avatar answered Oct 24 '22 10:10

Alexey Andreev