交易未激活 - Hibernate - JPA

时间:2013-11-20 13:07:53

标签: java hibernate jpa

我有这个类专门用于通过hibernate的persistance层在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有两个fk到同一个表TEquipements,而我,我保留TEquipements的数据,然后是TLinkEquipement

的数据

4 个答案:

答案 0 :(得分:7)

可能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
}

答案 1 :(得分:2)

对于可能会收到此错误消息的其他人: "线程中的异常" main" 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;
}

答案 2 :(得分:1)

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

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

我想说的关键点是请在你的代码中写下这个。

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

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

答案 3 :(得分:0)

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

SELECT sport, count(*) 
FROM activities 
WHERE username IN ('tony')
GROUP BY 1;