Java 休眠事务未成功启动

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

考虑以下简单的Hibernate场景:

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