Java 事务不活跃 - Hibernate - JPA
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20096856/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Transaction not active - Hibernate - JPA
提问by Houssem Badri
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
.
当我打印tx.isActive()
它给我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.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
实际上,该表TLinkEquipement
有 2 个 fk 到同一个表TEquipements
,而我,我保留了TEquipements
当时的数据TLinkEquipement
采纳答案by rzymek
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).
可能tx.begin()
抛出异常。这意味着在catch
子句中没有要回滚的活动事务。这就是为什么tx.rollback()
抛出另一个异常(隐藏原始错误)。
To see the source exception rewrite your catch
block:
要查看源异常重写您的catch
块:
} 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.
也不是说你在这里混合概念。一方面,您正在声明注入的实体管理器 ( @PersistenceContext
),另一方面,您正在以EntityManagerFactory
编程方式创建 using 。
If this is a JEE bean, it should look like this:
如果这是一个 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
}
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
}
回答by joshpt
For others who may get this error messsage: "Exception in thread "main" java.lang.IllegalStateException: Transaction not active"
对于可能收到此错误消息的其他人:“线程“main”中的异常 java.lang.IllegalStateException: Transaction not active”
Check your merge operation. You may be trying to merge an object that is supposed to be a reference instead of an object you just created. By reference, I mean... you need to have a live reference to that object from the database... hence the "transaction not active" error message.
检查您的合并操作。您可能正在尝试合并一个应该是引用的对象,而不是您刚刚创建的对象。通过引用,我的意思是...您需要从数据库中对该对象进行实时引用...因此会出现“事务未激活”错误消息。
Here is an example piece of code for querying an object from the database with JPQL:
下面是一段使用 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;
}
回答by HeyLink
I just came across this problem, and now I had solved it. But I realize that I was so stupid.
我刚刚遇到这个问题,现在我已经解决了。但我发现我太愚蠢了。
the reason I find is that the data I want to commit has a foreign key but I forget that, so the transaction will always close itself. I add the foreign key in the database, and then the test or main method run successfully.
我发现的原因是我想提交的数据有一个外键,但我忘记了,所以事务总是会自行关闭。我在数据库中添加了外键,然后test或者main方法就运行成功了。
the Key point I want to say is that please write this in your code.
我想说的关键点是请在您的代码中写下这个。
} catch (Exception ex) {
ex.printStackTrace();
tx.rollback();}
and you will easily find the reason why the transaction closed or not alive. that is my experience,hope useful!
你会很容易找到交易关闭或不活跃的原因。这是我的经验,希望有用!
回答by Antonio Petricca
I am using Hibernate 5.3.1.Finalwith Weblogic 12.2.1.2, and I solved the issue by the following persistence.xmlconfiguration:
我正在使用Hibernate 5.3.1.Final和Weblogic 12.2.1.2,我通过以下persistence.xml配置解决了这个问题:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
<persistence-unit name="mainPU" transaction-type="JTA">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>${wls.datasource}</jta-data-source>
<properties>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect"/>
<!-- https://issues.jboss.org/browse/FORGE-621?_sscc=t -->
<property name="hibernate.transaction.jta.platform" value="org.hibernate.engine.transaction.jta.platform.internal.WeblogicJtaPlatform" />
</properties>
</persistence-unit>
</persistence>