I have queries as below:
What is the difference of these two?
Are both of these supported by all databases?
Are JPA TransactionManager and JTA TransactionManager different?
JPA implementations have the choice of managing transactions themselves (RESOURCE_LOCAL), or having them managed by the application server's JTA implementation.
In most cases, RESOURCE_LOCAL is fine. This would use basic JDBC-level transactions. The downside is that the transaction is local to the JPA persistence unit, so if you want a transaction that spans multiple persistence units (or other databases), then RESOURCE_LOCAL may not be good enough.
JTA is also used for managing transactions across systems like JMS and JCA, but that's fairly exotic usage for most of us.
To use JTA, you need support for it in your application server, and also support from the JDBC driver.
As an addition to other answers
Here is an excerpt from the extremely useful article (published on the Apache TomEE website), which can also help answer the OP's first question (the link to the article is below).
Comparing RESOURCE_LOCAL and JTA persistence
contexts
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)
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
Anyone interested in learning the Java Persistence API - please do yourself a favor and read the full article here: JPA Concepts: JPA 101.
Resource_Local and JTA are transaction managers (methods of doing transactions). This is not the property of database but the component responsible for coordinating transactions. JPA and JTA transaction managers are different. JPA transaction manager is responsible for JPA transactions and you want to use one if you are only doing JPA transaction. JTA transaction manager is general purpose transaction manager and can enlist other resources such as JMS queues in transaction. Typically Java EE containers employ a JTA transaction manager for EJBs, JPA entities, etc.
resource_local vs JTA its about local transaction vs global transaction. It's about can we manage multiple resources under a single transaction.
CMT vs BMT its about who is opening and closing transaction - application developer or application server.
Related
I am just learning JTA and can't understand if I should use it if I have only one database. Currently I use hibernate 5 as JPA provider and if I need to use one transaction between methods I just pass EntityManager as argument.
However, I don't like this method as I need to remember if transaction is opened or not. I would like to find any library that will help me to control transactions (but without Spring) in SE environment. So, should I use JTA in my situation or should I use something different?
Normally when talking about JTA , it refers to the distributed transaction across multiple systems (e.g. across two databases , one database and one JMS compliant message broker). If you only have one database , it is not necessary to use JTA transaction although it should also work. Instead, use a local transaction for one database which should theoretically faster than using JTA transaction.
On the other hands , if you are just talking about #Transactional defined in the JTA , which allow you to declaratively control the transaction boundary by annotating it on a method and without passing the EntityManager between methods , you should look into which frameworks support it.
Under the cover , a proxied EntityManager is injected into different classes such that when it is invoked , it will get the actual EntityManager from the ThreadLocal. So every class in the same thread will get the same EntityManager which prevent you from passing the EntityManager around the methods. A new EntityManager instance will be set to the ThreadLocal just before the #Transactional method is executed using some sort of AOP technique.
Please note that #Transcational is nothing to do with the underlying transaction is JTA or local transaction. It should work for both transaction type.
I would use a framework that support #Transactional such as Spring , Quarkus or Micronaut etc , and configure Hibernate to use local transaction but not JTA transaction for single database.
In my hibernate.cfg.xml file, one of the properties is -
<property name = "transaction.factory_class"> <!--1-->
org.hibernate.transaction.JDBCTransactionFactory <!--2-->
</property> <!--3-->
Other properties are easy to understand. But, many questions came to my mind when I saw the above property.
line 1 - this specifies the class implementing the Transaction*Factory* interface.
Q1 - I saw the java docs for TransactionFactory but did not understand what it really is. What does this "Factory" mean ? Why don't they call it TransactionGenerator as per the line -
Contract for generating Hibernate Transaction instances.
Q2 - TransactionFactory lead me to Transaction. Is this exactly the same as a Database transaction ?
Q3 -
A single session might span multiple transactions since the notion of
a session (a conversation between the application and the datastore)
is of coarser granularity than the notion of a transaction. However,
it is intended that there be at most one uncommitted Transaction
associated with a particular Session at any time.
...the notion of a session is of coarser granularity than the notion of a transaction.
What does that mean in simple words ?
--
However, it is intended that there be at most one uncommitted
Transaction associated with a particular Session at any time.
Why do you intend this ?
I don't think that the API docs are clear. Makes a n00b life miserable.
Q1 - The reasoning is clear. The transaction creation follows a factory pattern. For example, in an environment where application servers (like JBOSS, WebSphere etc) manage the transaction creation via JTA APIs, you will use a JTA Transaction factory to create transactions and that transactions will be further used by hibernate. In a purely Spring managed environment, Spring can be configured to use a HibernateTransactionFactory. In short, it would follow a similar fashion as:
IFactory f= FactoryCreatorForYourEnvironment.create();
Transaction t = f.create();
Q2 and Q3 - Yes, a hibernate transaction factory creates database transactions on underlying DB. Note that a session may be spanning over multiple transactions - A hibernate session abstracts a database connection. Over the same connection, multiple begin transaction, commit transaction cycles are possible. Example: REQUIRE_NEW properties if the participating beans (EJBs, or SPRING beans). So session is a broader (coarser) term as mentioned in the documentation.
Transactions are required for any writes, deletes, protected reads. So the session holds an implicit transaction. You can read a related stack overflow article here.
HTH.
I am using Hibernate to map objects to entities and I have started to use an Entity Manager. This might be a silly question but what actually is the reason for using the entity manager? Previously I would have used a HibernateSessionFactory to get a session and then use that session to pull/push data.
Because the EntityManager is part of the standard - JPA. Theoretically, you can switch implementations (Hibernate, EclipseLink, OpenJPA) if you need to. Apart from alleged portability there isn't such a big difference between the two.
Hibernate implements the JPA standard. In fact, the EntityManager has a delegate, based on the concrete implementation. For Hibernate the delegate is the Session. If you call getDelegate() it will return the current Session.
I've always used hibernate with JPA (EntityManager) and had very rarely had the need to obtain the Session.
EntityManager is a concept of JPA.
You dont need to use JPA with Hibernate at all (in fact, if it's JPA1, I would suggest you dont).
You use an EntityManager when you are using JPA API. Hibernate implementation of EntityManager internally calls HibernateSessionFactory and manages Hibernate sessions for you.
EntityManagers in JPA serve basically the same purpose as Hibernate sessions.
Title says it all: What is the difference between a UserTransaction and an EntityTransaction?
My rudimentary understanding is that UserTransaction is used when JTA is required (e.g. to do queries on mulitple things), and that EntityTransaction is used when JPA only is required (e.g. when the query is atomic).
Is that the only difference between the two or is there more to it than that?
My rudimentary understanding is that
UserTransaction is used when JTA is
required (e.g. to do queries on
mulitple things), and that
EntityTransaction is used when JPA
only is required (e.g. when the query
is atomic).
That's basically right, but your description of "multiple things" and "atomic" is a bit strange. JTA allows the developper to use distributed transaction to perform changes on multiples resources (database, JMS broker, etc.) atomically (all-or-nothing). If only one resource is accessed (e.g. one single database), you don't need JTA, but the transaction is still atomic (all-or-nothing). That's for instance the case when you use a regular JDBC transaction on one database.
Considering UserTransaction vs. EntityTransaction:
If JPA is use stand-alone, you use EntityTransaction to demarcate the transaction yourself.
If JPA is used within a managed environment where it integrates with JTA, you use UserTransaction. The EntityManager hooks itself into the JTA distributed transaction manager. The only subtlety I'm aware of considers the flush of the changes. When EntityTransaction is used, JPA know it needs to flush the changes. If transaction are controlled using UserTransaction, it needs to register a callback using JTA registerSynchronization, so that the changes are flushed to the database before the transaction completes. If you use EJB with CMT (container managed transaction), you don't even need to use UserTransaction: the app server starts and stops the transactions for you.
Related questions:
What is difference between UserTransaction and EntityManager.getTransaction() (duplicate)
XA and non-XA datasource with Spring/Hibernate (related)
Does Seam support multiple persistence units in its configuration? Also, when would you want to have or need multiple persistence units?
I am working on a generic component and right now, it only supports a single persistence unit which makes sense to me as I have never used more than 1 persistence unit per web application. So, I am having difficulty seeing where you would use more than a single persistence unit.
Thanks,
Walter
Does Seam support multiple persistence units in its configuration?
I don't see why it wouldn't. Configure several persistence units and get them injected by name:
#PersistenceContext(unitName="UNITNAME")
private EntityManager em;
Also, when would you want to have or need multiple persistence units?
If you need to access multiples datasources.
It's very well possible to have multiple persistence units in JPA and in JPA with Seam. In Seam it's very easy. Just create more than one <persistence-unit name="myapp" /> elements in your persistence.xml and configure an EntityManagerFactory for each unit, and optionally an EntityManager for each EntityManagerFactory. You can then simply inject any EntityManager in the standard way:
#In
EntityManager entityManagerOne;
where your EntityManager is named entityManagerOne (and the other entityManagerTwo).
The most important reason to have multiple persistence units is the requirement to work with multiple database systems. This is not related to a data source, but the issue is simply to define a scope for your entity mappings.
Another reason is that you choose a transaction strategy (global (JTA) or local (resource-local)) per persitence unit. So, if you need to work with multiple transaction strategies you can create 2 persistence units for the same database.