交易未激活 - Hibernate - JPA

Hou*_*dri 6 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
}
Run Code Online (Sandbox Code Playgroud)

问题是它不会持久存储数据.

堆栈是:

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)
Run Code Online (Sandbox Code Playgroud)

但我必须指出,它在其他类中工作正常.

更新:

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

UPDATE

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

我遇到了问题所在:

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)
Run Code Online (Sandbox Code Playgroud)

事实上,该表TLinkEquipement有2 fk到同一个表TEquipements,而我,我坚持TEquipements那些的数据TLinkEquipement

rzy*_*mek 7

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

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

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

也不是说你在这里混合概念.一方面,您正在声明注入的实体管理器(@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
}
Run Code Online (Sandbox Code Playgroud)

这里,事务管理和实体管理器管理由容器(应用程序服务器)处理.


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

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
}
Run Code Online (Sandbox Code Playgroud)