Java 休眠事务未成功启动
考虑以下简单的Hibernate场景:Java 休眠事务未成功启动,java,hibernate,Java,Hibernate,考虑以下简单的Hibernate场景: session = getHibernateSession(); tx = session.beginTransaction(); SomeObject o = (SomeObject) session.get(SomeObject.class, objectId); tx.commit(); 此代码产生以下异常: org.hibernate.TransactionException: Transaction not successfully start
session = getHibernateSession();
tx = session.beginTransaction();
SomeObject o = (SomeObject) session.get(SomeObject.class, objectId);
tx.commit();
此代码产生以下异常:
org.hibernate.TransactionException: Transaction not successfully started
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:100)
at com.bigco.package.Clazz.getSomeData(Clazz.java:1234)
发生了什么?好吧,看起来一旦我们到达
tx.commit()
行,事务就已经提交了。我唯一的猜测是,当get()
初始化对象时,Hibernate已经提交了事务
解决方法很简单:
// commit only if tx still hasn't been committed yet (by hibernate)
if (!tx.wasCommitted())
tx.commit();
这是一个非常古老的问题,我想你已经解决了它(或者放弃了Hibernate),但答案非常简单。我很惊讶没有人捡到它 您尚未完成会话.save(o),因此事务中没有要提交的内容。如果没有更改对象中的任何内容,提交可能仍然不起作用,但是如果没有更改,为什么要保存它
顺便说一句:在会话之前执行session.get(…)也是完全可以接受的。beginTransaction()。我知道这已经解决了;即使我在这里张贴我的答案 我没有在事务上找到
wascommited()
方法
但以下代码对我有效:
// commit only, if tx still hasn't been committed yet by Hibernate
if (tx.getStatus().equals(TransactionStatus.ACTIVE)) {
tx.commit();
}
这种情况可能发生的一种情况是,代码位于使用容器管理事务(CMT)的EJB/MDB中,这可能是有意的,也可能是因为它是默认的。要使用bean管理的事务,请添加以下注释: @TransactionManagement(TransactionManagementType.BEAN)
还有更多,但这只是故事的开始。删除会话。关闭();从您的程序中,很少有更大的事务需要更多的时间,并且在关闭连接时会出现问题。仅使用session.flus()。您应该检查是否使用了此session.getTransaction().commit();或者回滚命令,因为hibernate的更高版本通过使用
@事务性(propagation=propagation.SUPPORTS,readOnly=false,rollboor=Exception.class)注释您可以避免任何与事务相关的异常。以上解决方案对我没有帮助,这就是我希望共享解决方案的原因 在我的例子中,我没有在我的一个实体中正确使用@Column注释。我把代码从
@Column(columnDefinition = "false")
private boolean isAvailable;
到
它成功了
我在dao中的创建方法
public int create(Item item) {
Session session = sessionFactory.getCurrentSession();
try {
int savedId = (int) session.save(item);
return savedId;
} catch (Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
return 0; //==> handle in custom exception
}
}
您也使用事务管理器吗?我不确定配置是什么,但假设我们有事务管理器,这会影响上述行为吗?我已经读到,有时手动创建事务,就像您在事务管理器在场的情况下一样,会导致事务抛出此异常。这是一个非常好的问题,答案令人难以置信。当通过get(…)检索实体时,为什么Hibernate会提交事务?我还没有在Hb文档中找到这个问题的答案。是因为get检查底层事务,然后使用它进行选择,然后提交它吗?我希望看到关于这个问题的更详细的答案。所以,如果我不更改数据库,我不应该开始发送?我建议谨慎使用这种方法。我认为只有当autocommit开启时,这才是可以接受的,而Hibernate极力阻止这一点。没有自动提交,一切都必须在一个事务中发生——即使是单个select语句。建议的解决方案对我很有效。想知道是否有一种智能方法可以找到事务提交的位置?您能告诉@TransactionManagement属于哪个包吗?。我在我的classpath
javax.ejb.TransactionManagement
中找不到它。看,这个答案似乎并不是对特定问题的回答。没有会话。关闭()
public int create(Item item) {
Session session = sessionFactory.getCurrentSession();
try {
int savedId = (int) session.save(item);
return savedId;
} catch (Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
return 0; //==> handle in custom exception
}
}