Adam Bien's Weblog

Friday Jun 24, 2011

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



*NEW* Workshop: "Effective Java EE 6/7", July 10th, Airport Munich

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 10:37 AM CEST #

I think glassfish complains if use this and doesn't start the entitymanager.

Posted by Goutham on June 24, 2011 at 11:10 AM 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 11:35 AM 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 11:45 AM 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 01:04 PM CEST #

... using drop-and-create-tables in production is quite destructive ...

Posted by Financial Michael on June 24, 2011 at 04: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 06: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 24, 2011 at 11:28 PM 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 24, 2011 at 11:31 PM 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 12:19 AM CEST #

Post a Comment:
  • HTML Syntax: NOT allowed
Meta
My Recent Book
Java One 2009/2011
...the last 150 posts
...the last 10 comments
Links
License