开发者

Hibernate transaction not successfully started

Consider this simple Hibernate scenario:

session = getHibernateSession();
tx = session.beginTransaction();
SomeObject o = (SomeObject) session.get(SomeObject.class, objectId);
tx.commit();

This code produces the following exception:

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)

What's going on?


Well, it looks like once we reach the tx.commit() line, the transaction has already been committed. My only guess is that Hibernate already commits the transaction when get()ing the object.

The fix for this is simple:

// commit only if tx still hasn't been committed yet (by hibernate)
if (!tx.wasCommitted())
    tx.commit();


This is a really old question and I figure you've already solved it (or given up on Hibernate) but the answer is tragically simple. I'm surprised no one else picked it up.

You haven't done a session.save(o), so there is nothing in the transaction to commit. The commit may still not work if you haven't changed anything in the object, but why would you want to save it if nothing has changed?

BTW: It is also perfectly acceptable to do the session.get(...) before the session.beginTransaction().


I got to know that this is already solved; even though I am posting my answer here.

I haven't found wasCommitted() method on the transaction.

But the following code worked for me:

// commit only, if tx still hasn't been committed yet by Hibernate
if (tx.getStatus().equals(TransactionStatus.ACTIVE)) { 
    tx.commit();
}


One situation this can happen in is when the code is in an EJB/MDB using container-managed transactions (CMT), either intentionally or because it's the default. To use bean-managed transactions, add the following annotation:

@TransactionManagement(TransactionManagementType.BEAN)

There's more to it than that, but that's the beginning of the story.


remove session.close(); from your program as few of the bigger transaction require more time and while closing the connection problem get occurred. use session.flus() only.


You should check weather you have used this session.getTransaction().commit(); or rollback command as higher version of hibernate removed manual code interaction by using @Transactional(propagation = Propagation.SUPPORTS, readOnly = false, rollbackFor = Exception.class) annotation you can avoid any transaction related exception.


Above solutions were not helpful for me and that is why I want to share my solution.

In my case, I was not using @Column annotation properly in one of my entity. I changed my code from

@Column(columnDefinition = "false") 
private boolean isAvailable;

to

@Column(columnDefinition = "boolean default false") 
private boolean isAvailable;

And it worked.

My create method in 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
        }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜