Don't use JPA's RESOURCE_LOCAL on the server
The JPA 1.0 / 2.0 specifications are clear about the JTA or / RESOURCE_LOCAL usage on application servers:"The transaction-type attribute is used to specify whether the entity managers provided by the entity manager factory for the persistence unit must be JTA entity managers or resource-local entity managers. The value of this element is JTA or RESOURCE_LOCAL. A transaction-type of JTA assumes that a JTA data source will be provided—either as specified by the jta-data-source element or provided by the container. In general, in Java EE environments, a transaction-type of RESOURCE_LOCAL assumes that a non-JTA datasource will be provided. In a Java EE environment, if this element is not specified, the default is JTA. In a Java SE environment, if this element is not specified, the default is RESOURCE_LOCAL."
see Section 184.108.40.206, Page 312 from JSR-317 If you deploy the following persistence.xml:
into a Java EE application server, you will also have to manage both: the EntityManager and it's JTA-transaction by yourself. This will end up with lots of plumbing. Instead of RESOURCE_LOCAL, you should use the JTA setting in production. With the JTA setting you don't have to specify the JDBC-connection and use a preconfigured JTA datasource instead:
<persistence> <persistence-unit name="integration" transaction-type="RESOURCE_LOCAL"> <class>...AnEntity</class> <exclude-unlisted-classes>true</exclude-unlisted-classes> <properties> <property name="javax.persistence.jdbc.url" value="jdbc:derby:memory:testDB;create=true"/> <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver"/> <property name="eclipselink.ddl-generation" value="create-tables"/> </properties> </persistence-unit> </persistence>
[persistence.xml with RESOURCE_LOCAL was used for local integration tests of x-ray. See also page 109 "Unit Test Is Not Integration Test" in Real World Java EE Night Hacks--Dissecting the Business Tier.]
<persistence> <persistence-unit name="prod" transaction-type="JTA"> <jta-data-source>jdbc/sample</jta-data-source> <properties> <property name="eclipselink.ddl-generation" value="drop-and-create-tables"/> </properties> </persistence-unit> </persistence>
I really like "Unit Test Is Not Integration Test" ... I think a lot of people should read this specific post line.
Posted by Bogdan Marian on June 24, 2011 at 12:37 PM CEST #
I think glassfish complains if use this and doesn't start the entitymanager.
Posted by Goutham on June 24, 2011 at 01:10 PM CEST #
Is there any other drawback of using RESOURCE_LOCAL (other than plumbing)?
And, are there any drawbacks of using JTA?
Posted by Michal Huniewicz on June 24, 2011 at 01:35 PM CEST #
there is no known drawback for JTA: you can still manage transactions manually (what I never did).
The drawback using RESOURCE_LOCAL is extreme: you will have to remember to rollback transactions in case exceptions happened, fetch EntityManager in each operation. It is also hard to perform several methods in a single transactions, because you will have to pass the EM / EntityTransactions to the dependent classes.
With RESOURCE_LOCAL you are re-implementing the already existing application server functionality - what is criminal :-)
thanks for your comment!,
Posted by Adam Bien on June 24, 2011 at 01:45 PM CEST #
Thanks for your reply, Adam.
This post comes in handy, I am about to make a JTA/non-JTA decision for my app. Great blog.
Posted by Michal Huniewicz on June 24, 2011 at 03:04 PM CEST #
... using drop-and-create-tables in production is quite destructive ...
Posted by Financial Michael on June 24, 2011 at 06:01 PM CEST #
I was creating a project where I was using JPA. But I was using Apache TomCat as a webcontainter so I didn't have an Entity Manager managed by container. Given this scenario I fall into using alternative ways to manage my EntityManager as is described at this blog:
I'd like to know another way to do it (more simple) without stopping to use tomcat.
Congrats for your great blog.
Posted by Adolfo Eloy on June 24, 2011 at 08:25 PM CEST #
in your case the solution is simple:
use TomEE: http://openejb.apache.org/3.0/apache-tomee.html
Plain Old Web Containers are dead: http://www.adam-bien.com/roller/abien/entry/are_plain_old_webcontainers_still
Posted by Adam Bien on June 25, 2011 at 01:28 AM CEST #
I achieved the best performance with the drop-and-create-tables in production so far :-)
A good catch. But: it actually shouldn't matter. The resource user should not have the rights to drop the tables.
thanks for diligent reading!,
Posted by Adam Bien on June 25, 2011 at 01:31 AM CEST #
With CDI I don't think RESOURCE_LOCAL should be avoided. I personally favor JTA EntityManagers.
However Arne recommends using it, because he believes in RequestScoped _extended_ PersistenceContexts. RESOURCE_LOCAL + CDI Producer/Disposer Methods and you are done. Of course you need to ensure that your persistence exceptions abort EntityManager interaction.
Posted by Jens Schumann on July 01, 2011 at 02:19 AM CEST #
Life saver post...... Thanks a billion.
Posted by Sam Mohamed on October 07, 2012 at 08:42 AM CEST #
Does this suggestion, to use JTA instead of RESOURCE_LOCAL apply to any ORM implementation, say, Hibernate for instance?
Posted by Eddy on May 11, 2013 at 05:34 AM CEST #
yes, JPA is only a thin wrapper (actually a standardized API) around Hibernate. It will also work with JPA / Hibernate, JPA / EclipseLink, JPA / openJPA etc.
Posted by Adam Bien on May 14, 2013 at 11:26 AM CEST #
I had to use RESOURCE_LOCAL on Server (JBoss). Because I only know which datasource shall be used on the call of the business logic (method). I tried to use JPA and CMT, but I found no way to have dynamic datasources in this case. All examples are using fixed datasource names in the persistence.xml, which I can not do. So I had to use RESOURCE_LOCAL, BMT and do the EntityManager(Factory) stuff by myself. Or is there another possibility which I have missed?
Posted by Oliver Pfau on July 16, 2013 at 12:07 PM CEST #
Thanks, nice tip.
Posted by Binh Thanh Nguyen on May 29, 2014 at 06:49 AM CEST #
I am building an application using afterburner and using the same persistence configuration of airhacks-control, but i have two entity classes so i have created two entity service classes for transaction now how to manage these transaction. Because when i am calling the select query it's giving an exception like - Column 'columnName' is either not in any table in the FROM list or appears within a join specification and is outside the scope of join specification or appears in a having clause and is not in the GROUP BY list.
Posted by Nazim on March 15, 2015 at 05:49 PM CET #
For Databases, if JTA is used then XADataSources neede to be provided .
In a Java EE environment , if transaction-type is JTA , but data source registered is not XA data source , then how things work?
Posted by Ravneet Singh on February 13, 2016 at 12:42 PM CET #