Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPA - When to use getTransaction() when persisting objects

I've recently started working with JPA on the Google App Engine. In reading some examples, I've noticed a couple of variations in the way objects are persisted. In one case, I've seen something like this:

entityManager.getTransaction().begin();
entityManager.persist(object);
entityManager.getTransaction().commit();

In other cases, I don't see the use of getTransaction(). I simply see entityManager.persist(object). When is it appropriate to use getTransaction()?

like image 336
John F. Avatar asked Dec 11 '11 13:12

John F.


3 Answers

If you use container managed EntityManager then you're using JTA transactions. Hence, you don't need to (more precisely - you can not) interfere with EntityManager's transactions fetched using entityManager.getTransaction(). The JTA starts and commits your transaction.

If you use application managed EntityManager and you don't want to be in part of JTA transaction, then you need to manage them for yourself (it's called a resource-local entity manager).

Most typically, application managed EntityManager which works with EntityManager.getTransaction() is used in Java SE environment.

EDIT: You might be interested in secion 7.5 Controlling Transactions from the JPA 2.0 specification.

like image 106
Piotr Nowicki Avatar answered Oct 20 '22 22:10

Piotr Nowicki


In GAE there is no Java EE/JTA so ignore terms such as bean managed transaction (BMT), and container managed transactions (CMT).

Your work is either transactional (where you want multiple objects to go to the datastore at once, or all to fail - this is where you have getTransaction() used), or nontransactional (where everything goes to the datastore one by one, and the failure of one persist doesn't affect others - this is where you just call persist()/merge()/remove()).

like image 5
DataNucleus Avatar answered Oct 20 '22 22:10

DataNucleus


Google App Engine has its transaction management (https://developers.google.com/appengine/docs/java/datastore/transactions) but the JPA transaction interface isn't aware of some of the GAE underlying functionalities (i.e. entity groups).

So it’s up to your application to decide which operations to perform in a transaction and which not. You should put in a transaction operations that have to be executed atomically.

Remember as a best practice to perform cascading actions and relationship operations in a transaction because JPA might trigger many queries and it could lead to an inconsistent data situation.

Example of using transaction with JPA2:

import javax.persistence.EntityTransaction;


EntityTransaction txn = em.getTransaction();
txn.begin();
try {
    //do something with your database
    txn.commit();
} 
finally {
   if (txn.isActive())
      txn.rollback(); 
}
like image 4
andreacipriani Avatar answered Oct 20 '22 21:10

andreacipriani