【问题标题】:Transaction not active - Hibernate - JPA事务不活跃 - 休眠 - JPA
【发布时间】:2013-11-20 13:07:52
【问题描述】:

我有这个类,专门通过hibernate的持久层将数据持久化到db中。

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
}

问题是它不持久化数据。

堆栈是:

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)

但我必须注意,它在其他类中也可以正常工作。

更新

当我打印tx.isActive() 时,它给了我false

更新

我试图获取更多有关错误的信息:

我知道问题出在哪里了:

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)

事实上,TLinkEquipement 的表有 2 个 fk 到同一个表TEquipements,而我,我坚持TEquipements 的数据然后是TLinkEquipement 的数据

【问题讨论】:

    标签: java hibernate jpa


    【解决方案1】:

    可能tx.begin() 抛出了异常。这意味着在catch 子句中没有要回滚的活动事务。这就是tx.rollback() 引发另一个异常的原因(掩盖了原始错误)。

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

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

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

    如果这是一个 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
    }
    

    这里事务管理和实体管理器管理由容器(应用服务器)处理。


    如果这个类在容器之外使用,那么我可能看起来像这样:

    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
    }
    

    【讨论】:

    • 没用,其实不是J2EE应用,只是一个swing应用,使用Hibernate作为持久层来保存un mysql db。正如我所说,ti 可以与其他一些类一起正常工作(我是 Hibernate 的新手)
    • tx 没有名为 getStatus 的方法
    • 哦,对了。 tx.getStatus()UserTransaction 中。 isActive() 可能对您不起作用,因为您在方法调用之间共享 tx 对象(它是一个字段而不是变量)。
    【解决方案2】:

    对于可能收到此错误消息的其他人: “线程“主”java.lang.IllegalStateException 中的异常:事务未激活”

    检查您的合并操作。 您可能正在尝试合并一个应该是引用的对象,而不是您刚刚创建的对象。通过引用,我的意思是...您需要从数据库中对该对象进行实时引用...因此出现“事务未激活”错误消息。

    以下是使用 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;
    }
    

    【讨论】:

      【解决方案3】:

      我刚刚遇到这个问题,现在我已经解决了。但我意识到我是如此愚蠢。

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

      我想说的重点是,请把这个写在你的代码中。

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

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

      【讨论】:

        【解决方案4】:

        我正在使用 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>
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2016-03-19
          • 2015-12-13
          • 2015-08-30
          • 1970-01-01
          • 2017-07-27
          • 1970-01-01
          • 2018-12-31
          相关资源
          最近更新 更多