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()
?
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:
You'd use
getTransaction()
when you're explicitly handling the transactions in your application. On the other hand, if you let the container handle the transactions for you, it won't be necessary to explicitly begin/end transactions. Essentially, we're dealing with the difference between Container Managed Transactions (CMT) and Bean Managed Transactions (BMT).In general, you'd use BMT when you need more control over the transactional processing, or when there are additional technical requirements (for instance, two-phase commits, distributed transactions, XA transactions) that can't be met by using CMT. Also, you'd use BMT when your applications is deployed outside of an application server and relies on Java SE.
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()).
If you use container managed
EntityManager
then you're using JTA transactions. Hence, you don't need to (more precisely - you can not) interfere withEntityManager
's transactions fetched usingentityManager.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 withEntityManager.getTransaction()
is used in Java SE environment.EDIT: You might be interested in secion 7.5 Controlling Transactions from the JPA 2.0 specification.