我有一个专门用于通过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。
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
TLinkEquipement
TEquipements
可能tx.begin()引发了异常。这意味着该catch子句中没有要回滚的活动事务。这就是为什么tx.rollback()引发另一个异常(隐藏原始错误)的原因。
tx.begin()
catch
tx.rollback()
要查看源异常,请重写您的catch块:
} catch (RuntimeException re) { log.error("persist failed", re); //moved to top tx.rollback(); throw re; }
同样不是在这里混概念。一方面,您要声明注入的实体管理器(@PersistenceContext),另一方面,您是通过EntityManagerFactory编程方式创建的。
@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 }