0

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?

Meow
  • 18,371
  • 52
  • 136
  • 180
  • Your assumption about behaviour of the query is wrong - explicit queries are always executed immediately. – axtavt Feb 14 '11 at 10:49
  • @axtavt: but I've tested above code and the executeUpdate() does not get executed until commit is called. Or am I missing something??? – Meow Feb 14 '11 at 10:58
  • @axtavt: I put system.exit() between executeUpdate() and commit() and checked database and query result wasn't reflected. This is not true if I enable JTA in persistences.xml though. – Meow Feb 14 '11 at 11:08
  • These changes can't be seen in the database since transaction wasn't committed. I'm not sure about enabling JTA, but if you do it without JTA environment, perhaps you actually get something like auto-commit mode. After all, try to enable SQL logging to see when query is actually issued. – axtavt Feb 14 '11 at 11:24

1 Answers1

2

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.

Clement P
  • 3,243
  • 1
  • 19
  • 20