Java 事务不活跃 - Hibernate - JPA

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20096856/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 23:08:02  来源:igfitidea点击:

Transaction not active - Hibernate - JPA

javahibernatejpa

提问by Houssem Badri

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.

当我打印tx.isActive()它给我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.noCascade(CascadingAction.java:376)

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

实际上,该表TLinkEquipement有 2 个 fk 到同一个表TEquipements,而我,我保留了TEquipements当时的数据TLinkEquipement

采纳答案by rzymek

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

可能tx.begin()抛出异常。这意味着在catch子句中没有要回滚的活动事务。这就是为什么tx.rollback()抛出另一个异常(隐藏原始错误)。

To see the source exception rewrite your catchblock:

要查看源异常重写您的catch块:

} 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 EntityManagerFactoryprogrammatically.

也不是说你在这里混合概念。一方面,您正在声明注入的实体管理器 ( @PersistenceContext),另一方面,您正在以EntityManagerFactory编程方式创建 using 。

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

如果这是一个 JEE bean,它应该是这样的:

@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
}

回答by joshpt

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

对于可能收到此错误消息的其他人:“线程“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:

下面是一段使用 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;
}

回答by HeyLink

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.

我发现的原因是我想提交的数据有一个外键,但我忘记了,所以事务总是会自行关闭。我在数据库中添加了外键,然后test或者main方法就运行成功了。

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!

你会很容易找到交易关闭或不活跃的原因。这是我的经验,希望有用!

回答by Antonio Petricca

I am using Hibernate 5.3.1.Finalwith Weblogic 12.2.1.2, and I solved the issue by the following persistence.xmlconfiguration:

我正在使用Hibernate 5.3.1.FinalWeblogic 12.2.1.2,我通过以下persistence.xml配置解决了这个问题:

<?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>