Transaction not active - Hibernate - JPA

前端 未结 4 766
北恋
北恋 2020-12-19 07:02

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

public class TLinkEquipementDAOImpl implements TLinkEquipe         


        
相关标签:
4条回答
  • 2020-12-19 07:32

    I am using Hibernate 5.3.1.Final with Weblogic 12.2.1.2, and I solved the issue by the following persistence.xml configuration:

    <?xml version="1.0" encoding="UTF-8"?>
    <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
    
      <persistence-unit name="mainPU" transaction-type="JTA">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <jta-data-source>${wls.datasource}</jta-data-source>
        <properties>
          <property name="hibernate.show_sql" value="true"/>
          <property name="hibernate.format_sql" value="true"/>
          <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/>
    
          <!-- https://issues.jboss.org/browse/FORGE-621?_sscc=t -->
    
          <property name="hibernate.transaction.jta.platform" value="org.hibernate.engine.transaction.jta.platform.internal.WeblogicJtaPlatform" />
        </properties>
      </persistence-unit>
    </persistence>
    
    0 讨论(0)
  • 2020-12-19 07:33

    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;
    }
    
    0 讨论(0)
  • 2020-12-19 07:44

    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
    }
    
    0 讨论(0)
  • 2020-12-19 07:46

    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!

    0 讨论(0)
提交回复
热议问题