Yuval Adam
Yuval Adam

Reputation: 165182

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?

Upvotes: 30

Views: 86605

Answers (7)

Arun Kumar
Arun Kumar

Reputation: 333

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

Upvotes: 0

Virendra khade
Virendra khade

Reputation: 97

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.

Upvotes: 0

Virendra khade
Virendra khade

Reputation: 97

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.

Upvotes: 0

Yaqoob
Yaqoob

Reputation: 311

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.

Upvotes: 0

User0123
User0123

Reputation: 159

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();
}

Upvotes: 9

sedge
sedge

Reputation: 385

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().

Upvotes: 11

Yuval Adam
Yuval Adam

Reputation: 165182

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();

Upvotes: 55

Related Questions