77

In the persistence.xml JPA configuration file, you can have a line like:

<persistence-unit name="com.nz_war_1.0-SNAPSHOTPU" transaction-type="JTA">

or sometimes:

<persistence-unit name="com.nz_war_1.0-SNAPSHOTPU" transaction-type=”RESOURCE_LOCAL”>

My question is:

What is the difference between transaction-type="JTA" and transaction-type=”RESOURCE_LOCAL” ?

I also noticed some persistence.xml files with the transaction-type missing. Is it correct?

Germano Massullo
  • 2,572
  • 11
  • 40
  • 55

1 Answers1

127

Defaults

Default to JTA in a JavaEE environment and to RESOURCE_LOCAL in a JavaSE environment.

RESOURCE_LOCAL

With <persistence-unit transaction-type="RESOURCE_LOCAL"> you are responsible for EntityManager (PersistenceContext/Cache) creating and tracking

  • You must use the EntityManagerFactory to get an EntityManager
  • The resulting EntityManager instance is a PersistenceContext/Cache An EntityManagerFactory can be injected via the @PersistenceUnit annotation only (not @PersistenceContext)
  • You are not allowed to use @PersistenceContext to refer to a unit of type RESOURCE_LOCAL
  • You must use the EntityTransaction API to begin/commit around every call to your EntityManger
  • Calling entityManagerFactory.createEntityManager() twice results in two separate EntityManager instances and therefor two separate PersistenceContexts/Caches.
  • It is almost never a good idea to have more than one instance of an EntityManager in use (don't create a second one unless you've destroyed the first)

JTA

With <persistence-unit transaction-type="JTA"> the container will do EntityManager (PersistenceContext/Cache) creating and tracking.

  • You cannot use the EntityManagerFactory to get an EntityManager
  • You can only get an EntityManager supplied by the container
  • An EntityManager can be injected via the @PersistenceContext annotation only (not @PersistenceUnit)
  • You are not allowed to use @PersistenceUnit to refer to a unit of type JTA
  • The EntityManager given by the container is a reference to the PersistenceContext/Cache associated with a JTA Transaction.
  • If no JTA transaction is in progress, the EntityManager cannot be used because there is no PersistenceContext/Cache.
  • Everyone with an EntityManager reference to the same unit in the same transaction will automatically have a reference to the same PersistenceContext/Cache
  • The PersistenceContext/Cache is flushed and cleared at JTA commit time
Jiri Kremser
  • 12,471
  • 7
  • 45
  • 72
  • I think you made a little mistake with the titles of the two lists: maybe you shuffled them? – Germano Massullo Jun 27 '13 at 07:59
  • 1
    and clearly you can use JTA in a JavaSE environment too, and get the EM yourself from the EMF ... such as when using a stand-alone JTA provider. Perhaps your lists refer to JavaSE and JavaEE as opposed to JTA and RESOURCE_LOCAL – DataNucleus Jun 27 '13 at 08:17
  • 5
    "It is almost never a good idea to have more than one instance of an EntityManager in use" -- Is this your opinion? It's often necessary to have multiple open EntityManagers open in a concurrent application. In general, a very good answer. – Samuel Aug 01 '14 at 15:29
  • 1
    I used RESOURCE_LOCAL without having the need to begin and end transactions myself. I think RESOURCE_LOCAL is more like "I wan to test this database using local test memory" which is very helpful for JUnit testing. – ha9u63a7 Jan 22 '15 at 01:16
  • With RESOURCE_LOCAL, may I use Persistence.createEntityManagerFactory() instead of @PersistenceUnit to get an EMF? – Zyl Feb 18 '15 at 09:53
  • @Zyl: what I understand you can but you are creating EMF completely out of the container management capabilities. That means that you will need to have jdbc driver on application class path and connection to database is needed to be specified via properties of PU. I mean tag won't be reflected as you connect "directly" to database. – chalda Mar 05 '15 at 16:21
  • 2
    I don't agree with statement that "You are not allowed to use @PersistenceUnit to refer to a unit of type JTA". I think that you can easily do so and you can use method emf.createEntityManager() to get entity manager. And you can use the argument of type SynchronizationType to define if current transaction should be joined immediately or you will join it yourself when calling em.joinTransaction() method – chalda Mar 05 '15 at 16:24
  • @ha9u63ar How would I inject my EntityManager using PersistenceContext annotation and LocalResource in my unit test? Do you have an example? – bobK Sep 30 '15 at 13:38
  • 4
    You may take a look at the source of the answer with addtional informations and short example: http://tomee.apache.org/jpa-concepts.html – Radium Apr 27 '16 at 13:26
  • I have using tomcat as the web server for deploying my application. Should i use "JTA" or "RESOURCE_LOCAL" ? – iftekhar khan Aug 25 '17 at 07:36