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 8.2.1.2, Page 312 from JSR-317

If you deploy the following persistence.xml:

<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>

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="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>

[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.]

Comments:

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 #

Hi Adam.

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 #

@Michal,

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!,

adam

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 #

Hi Adam.
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:

http://javanotepad.blogspot.com/2007/08/managing-jpa-entitymanager-lifecycle.html

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 #

@Adolfo,

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

:-)

thanks!,

adam

Posted by Adam Bien on June 25, 2011 at 01:28 AM CEST #

@Financial Michael

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!,

adam

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 #

@Eddy,

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.

thanks!,

adam

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 #

Hi Adam,
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.
Thank you.

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 #

Post a Comment:
  • HTML Syntax: NOT allowed
...the last 150 posts
...the last 10 comments
License