JPA with non-JTA: Is it possible to close EntityTransaction safely without commit?

3.3k views Asked by At

I'm using JPA Toplink-essential and developing RESTful web app.

Here is one thing to mention first.

Not using JTA

So my persistences.xml is defined not to use JTA.

 <persistence-unit name="kojoPU">    
        <provider>oracle.toplink.essentials.PersistenceProvider</provider>
        <non-jta-data-source>machinePrototype</non-jta-data-source>

This allows the entity manager not to execute query immediately with executeUpdate() It will wait til commit.

em.getTransaciton().begin();
Query query = em.createNativeQuery("DELETE FROM table1 WHERE theId = 10;");
query.executeUpdate(); //not yet executed until transaction is commited.

//continue do something...


em.getTransaction().commit(); //the query above is executed here finally

But there is one big problem, after transaction.begin(), is there is any error like JSONException or indexOutOfBoundsException, the transaction is not closed and kept open for a while.

Is it possible to force close the transaction somehow in such case?

1

There are 1 answers

1
Clement P On BEST ANSWER

Unless I missed something, you probably want something like:

em.getTransaciton().begin();
try {
  Query query = em.createNativeQuery("DELETE FROM table1 WHERE theId = 10;");
  query.executeUpdate(); //not yet executed until transaction is commited.

  //continue do something...

  em.getTransaction().commit(); //the query above is executed here finally
} catch (ex RuntimeException) {
  em.getTransaction().rollback();
} finally {
  // you probably also want something here to check the status of the transaction and rollback if you exited the try block somehow
}

However, I believe it's customary for transaction manager to rollback on commit failure but it seems like it's not happening for you.

Also, relying on the update query to run on commit is not a good idea since Hibernate can decide to run your update at any time (essentially doing a flush()). If you want to run the query at the very end, do it right before your commit.