2013-11-20 86 views
4

我有這個類,它致力於通過持久層的休眠數據在數據庫中持久化。事務沒有激活 - 休眠 - 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"); 
     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) 

但我要指出,這在其他類工作正常。

UPDATE

當我做的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) 
其實

,表TLinkEquipement有2 FK到同表TEquipements和我,我堅持數據TEquipements那麼那些TLinkEquipement

回答

6

可能tx.begin()引發異常。這意味着在catch子句中沒有活動事務要回滾。這就是爲什麼tx.rollback()引發另一個異常(陰影原始錯誤)。

看到源例外重寫catch塊:

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

而且不是你在這裏混合概念。一方面你聲明注入實體管理器(@PersistenceContext),另一方面你使用編程方式使用EntityManagerFactory創建。

如果這是一個JEE豆,它應該是這樣的:

@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 
} 
+0

請參閱更新請求 –

+0

回答擴展 – rzymek

+0

它沒有問題,事實上,它不是一個J2EE應用程序,它只是一個使用Hibernate作爲持久層來保存un mysql db的swing應用程序。正如我所說,ti與其他一些類的工作正常(我在Hibernate中是newbye) –

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; 
} 
1

我只是碰到這個問題,現在我已經解決了它。但我意識到我很愚蠢。

我發現的原因是我想提交的數據有一個外鍵,但我忘記了,所以事務總是會自動關閉。我在數據庫中添加外鍵,然後測試或主方法成功運行。

我想說的關鍵點是請在您的代碼中寫下此內容。

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

而且您將很容易找到事務關閉或不活動的原因。 那是我的經驗,希望有用!