事务未激活 - Hibernate - JPA [英] Transaction not active - Hibernate - JPA
问题描述
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);
尝试{
tx.begin();
entityManager.persist(transientInstance);
tx.commit();
log.debug(坚持成功);
} catch(RuntimeException re){
tx.rollback();
log.error(persist failed,re);
throw re;
}
}
//员工
}
问题是它没有保存数据。
堆栈是:
线程main中的异常java.lang.IllegalStateException:事务未激活
在org.hibernate.ejb.TransactionImpl.rollback(TransactionImpl.java:82)
在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)
但我必须注意,它在其他类中正常工作。
$ b
更新:
当我打印 tx.isActive()
时,它会给我 false
。
更新
以获得有关错误的一些信息:
我得到了问题所在:
导致:org.hibernate.TransientObjectException:对象引用未保存的瞬态实例 - 在刷新前保存瞬态实例:sau.se.domain.model.TLinkEquipement.TEquipementsByIdEquipement2 - > sau.se.domain.model.TEquipements
at org.hibernate.engine.CascadingAction $ 9.noCascade(CascadingAction.java:376)
实际上,表 TLinkEquipement
对同一张表 TEquipements
有2个fk。 ,和我,我坚持数据 TEquipements
那么 TLinkEquipement
可能 tx.begin()
引发异常。这意味着在 catch
子句中没有活动事务要回滚。这就是为什么 tx.rollback()
抛出另一个异常(影响原始错误)。
要查看源异常,请重新编写您的 catch
块:
} catch(RuntimeException re){
log.error(persist failed,re); //移动到顶部
tx.rollback();
throw re;
$ b $ p $也不是你的'在这里重新混合概念。一方面你声明注入实体管理器( @PersistenceContext
),另一方面你使用 EntityManagerFactory
以编程方式。
如果这是一个JEE bean,它应该看起来像这样:
@Stateless
public class TLinkEquipementDAOImpl implements TLinkEquipementDAO {
private static final Log log = LogFactory.getLog(TLinkEquipementDAOImpl.class);
@PersistenceContext
私人EntityManager entityManager;
public void persist(TLinkEquipement transientInstance){
log.debug(persisting TLinkEquipement instance);
entityManager.persist(transientInstance);
log.debug(坚持成功);
}
//员工
}
这里的事务管理和实体管理器管理由容器(应用程序服务器)处理。
如果此类在容器外部使用,那么I可能看起来像这样:
public class TLinkEquipementDAOImpl implements TLinkEquipementDAO {
private static final Log log = LogFactory.getLog(TLinkEquipementDAOImpl 。类);
//假设getEntityManagerFactory()返回已经创建的EMF
私有EntityManagerFactory emf = PersistenceManager.getInstance()
.getEntityManagerFactory();
private EntityManager entityManager = emf.createEntityManager();
public void persist(TLinkEquipement transientInstance){
EntityTransaction tx = entityManager.getTransaction();
log.debug(持久化TLinkEquipement实例);
尝试{
tx.begin();
entityManager.persist(transientInstance);
tx.commit();
log.debug(坚持成功);
} catch(RuntimeException re){
log.error(persist failed,re);
if(tx.isActive()){
tx.rollback();
}
throw re;
}
}
//员工
}
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
.
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$9.noCascade(CascadingAction.java:376)
in fact, the table TLinkEquipement
has 2 fk to the same table TEquipements
, and me, i persist data of TEquipements
then those of TLinkEquipement
解决方案 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
}
这篇关于事务未激活 - Hibernate - JPA的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!