Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Transaction not active - Hibernate - JPA

I have this class which is dedicated to persist data in db through persistance layer of hibernate.

public class TLinkEquipementDAOImpl implements TLinkEquipementDAO {

    private static final Log log = LogFactory
            .getLog(TLinkEquipementDAOImpl.class);

    @PersistenceContext
    private EntityManagerFactory emf = PersistenceManager.getInstance()
            .getEntityManagerFactory();
    private EntityManager entityManager = emf.createEntityManager();

    private EntityTransaction tx = entityManager.getTransaction();

    public void persist(TLinkEquipement transientInstance) {
        log.debug("persisting TLinkEquipement instance");
        try {
            tx.begin();
            entityManager.persist(transientInstance);
            tx.commit();
            log.debug("persist successful");
        } catch (RuntimeException re) {
            tx.rollback();
            log.error("persist failed", re);
            throw re;
        }
    }
//Staff
}

The problem is that it does not persist data.

The stack is:

Exception in thread "main" java.lang.IllegalStateException: Transaction not active
    at org.hibernate.ejb.TransactionImpl.rollback(TransactionImpl.java:82)
    at sau.se.domain.dao.Impl.TLinkEquipementDAOImpl.persist(TLinkEquipementDAOImpl.java:47)
    at sau.se.domain.service.Impl.TLinkEquipementServiceImpl.persist(TLinkEquipementServiceImpl.java:29)
    at sau.se.extractor.InfoExtract.getAllSPData(InfoExtract.java:346)
    at sau.se.extractor.InfoExtract.main(InfoExtract.java:436)

But i have to note, that it works fine in other classes.

UPDATE:

when i make print of tx.isActive() it gives me false.

UPDATE

I tried to more get some info about the error:

I got where the problem is:

Caused by: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: sau.se.domain.model.TLinkEquipement.TEquipementsByIdEquipement2 -> sau.se.domain.model.TEquipements
    at org.hibernate.engine.CascadingAction$9.noCascade(CascadingAction.java:376)

in fact, the table TLinkEquipement has 2 fk to the same table TEquipements, and me, i persist data of TEquipements then those of TLinkEquipement

like image 286
Houssem Badri Avatar asked Nov 20 '13 13:11

Houssem Badri


3 Answers

Probably tx.begin() threw an exception. That means that in the catch clause there was no active transaction to rollback. That's why tx.rollback() threw another exception (shadowing the original error).

To see the source exception rewrite your catch block:

} catch (RuntimeException re) {
    log.error("persist failed", re); //moved to top
    tx.rollback();
    throw re;
}

Also not that you're mixing concepts here. On one hand you're declaring injected entity manager (@PersistenceContext), on the other hand you're creating using EntityManagerFactory programmatically.

If this is a JEE bean, it should look like this:

@Stateless
public class TLinkEquipementDAOImpl implements TLinkEquipementDAO {   
    private static final Log log = LogFactory.getLog(TLinkEquipementDAOImpl.class);

    @PersistenceContext
    private EntityManager entityManager;

    public void persist(TLinkEquipement transientInstance) {
        log.debug("persisting TLinkEquipement instance");
        entityManager.persist(transientInstance);
        log.debug("persist successful");
    }
//Staff
}

Here transaction management and entity manager management is handled by the container (application server).


If this class is used outside of a container then I could look like this:

public class TLinkEquipementDAOImpl implements TLinkEquipementDAO {   
    private static final Log log = LogFactory.getLog(TLinkEquipementDAOImpl.class);

    //I'm assuming getEntityManagerFactory() returnes an already created EMF
    private EntityManagerFactory emf = PersistenceManager.getInstance()
            .getEntityManagerFactory();
    private EntityManager entityManager = emf.createEntityManager();

    public void persist(TLinkEquipement transientInstance) {
        EntityTransaction tx = entityManager.getTransaction();
        log.debug("persisting TLinkEquipement instance");
        try {
            tx.begin();
            entityManager.persist(transientInstance);
            tx.commit();
            log.debug("persist successful");
        } catch (RuntimeException re) {
            log.error("persist failed", re); 
            if(tx.isActive()) {
                tx.rollback();
            }
            throw re;
        }
    }
//Staff
}
like image 121
rzymek Avatar answered Nov 07 '22 03:11

rzymek


For others who may get this error messsage: "Exception in thread "main" java.lang.IllegalStateException: Transaction not active"

Check your merge operation. You may be trying to merge an object that is supposed to be a reference instead of an object you just created. By reference, I mean... you need to have a live reference to that object from the database... hence the "transaction not active" error message.

Here is an example piece of code for querying an object from the database with JPQL:

public static Users getUserByName(EntityManager em, String name) throws NoResultException, Exception {
    Users user = null;
    user = em.createQuery("SELECT u from Users u WHERE u.name =:name", Users.class).setParameter("name", name).setMaxResults(1).getSingleResult();
    return user;
}
like image 29
joshpt Avatar answered Nov 07 '22 03:11

joshpt


I just came across this problem, and now I had solved it. But I realize that I was so stupid.

the reason I find is that the data I want to commit has a foreign key but I forget that, so the transaction will always close itself. I add the foreign key in the database, and then the test or main method run successfully.

the Key point I want to say is that please write this in your code.

} catch (Exception ex) {
ex.printStackTrace();
tx.rollback();}

and you will easily find the reason why the transaction closed or not alive. that is my experience,hope useful!

like image 43
HeyLink Avatar answered Nov 07 '22 03:11

HeyLink