users@jersey.java.net

Re: Cannot use an EntityTransaction while using JTA, cannot switch to application managed transactions

From: Jacob <skoczko_at_gmail.com>
Date: Wed, 9 Apr 2008 11:59:34 +0200

Hi Jakub,

After a short discussion with Peter Liu who, I believe, maintains the
JAX-RS plugin for Netbeans, we came to the conclusion that It might be
a jersey issue after all.

Short recap:

The plugin generates code that uses EntityTransaction and bean-managed
EntityManager to do all the persistence stuff. That works fine with
the resource-local transaction types but not so good with JTA
transaction-types.

In order to switch to JTA transactions you need to inject
UserTransaction and EntityManager (container-managed) or
EntityManagerFactory (bean-managed) through annotations:

@PersistenceUnit(unitName = "some_name")
private EntityManagerFactory emf;

private EntityManager getEntityManager() {
 return emf.createEntityManager();
}

@Resource
private UserTransaction utx;

However the following code results in:

javax.servlet.ServletException:
com.sun.ws.rest.api.container.ContainerException: Persistence unit
'some_name' is not configured as a servlet parameter in web.xml

the UserTransaction is not injected either (null).

Still, the persistence unit is specified in persistence.xml and
referenced in web.xml like I wrote in the previous post.

The quick and dirty (I'm not sure how portable that is between
containers) fix I found is to look-up both EntityManager and
UserTransaction through JNDI:

 private EntityManager getEntityManager() {
       EntityManager em = null;
       try {
           em = (EntityManager) new
InitialContext().lookup("java:comp/env/persistence/localindexes");
       } catch (NamingException e) {
           Logger.getLogger(HarvestablesResource.class.getName()).log(Level.SEVERE,
null, e);
       }
       return em;
   }

   private UserTransaction getUserTransaction() {
       UserTransaction utx = null;
       try {
           utx = (UserTransaction) new
InitialContext().lookup("java:comp/UserTransaction");
       } catch (NamingException e) {
           Logger.getLogger(HarvestablesResource.class.getName()).log(Level.SEVERE,
null, e);
       }
       return utx;
   }

That works, but forces you to use a container-managed EntityManager -
the injection way is far more generic and flexible.

Cheers,
Jakub


On Tue, Apr 8, 2008 at 11:39 AM, Jakub Podlesak <Jakub.Podlesak_at_sun.com> wrote:
>
> Hi Jacob,
>
> to me it seems as a Netbeans REST plugin issue
> rather than a Jersey issue.
>
> Could you please try to submit a new issue record at
> http://www.netbeans.org/issues
>
> Component: websvc
> Subcomponent: rest
>
> It would also help if you could attach your (zipped)
> NetbeansProject there.
>
> Thanks,
>
> ~Jakub
>
>
>
>
>
> On Tue, Apr 08, 2008 at 10:43:36AM +0200, Jacob wrote:
> > Hi All,
> >
> > I am using Netbeans to develop RESTful web services (using JAX-RS) on
> > top of entity beans anotated in JPA and persisted in MySQL. I tried
> > the built-in netbeans wizard to generate restful ws from entity beans.
> > However, when I try to access the web service I get a following
> > exception:
> >
> > java.lang.IllegalStateException:
> > Exception Description: Cannot use an EntityTransaction while using JTA.
> >
> >
> >
> > Indeed I'm using JTA in my persistence.xml, does it automatically mean
> > that I cannot use EntitytTransaction? If so, how do I persist and
> > merge objects? I cannot do it without a transaction because I'm
> > getting:
> >
> > javax.persistence.TransactionRequiredException
> >
> >
> >
> > I tried switching to application-managed transactions (and using the
> > UserTransaction instead of EntityTransaction) but I cannot get the
> > persistence unit to work. If I substitute the auto-genereated thread
> > local based PersistenceService and annotate my class with the
> > following:
> >
> > @PersistenceUnit(unitName = "localindexes")
> > private EntityManagerFactory emf;
> >
> > private EntityManager getEntityManager() {
> > return emf.createEntityManager();
> > }
> >
> > @Resource
> > private UserTransaction utx;
> >
> >
> > I get yet another exception:
> >
> > javax.servlet.ServletException:
> > com.sun.ws.rest.api.container.ContainerException: Persistence unit
> > 'localindexes' is not configured as a servlet parameter in web.xml
> >
> >
> > Putting:
> >
> > <persistence-context-ref>
> > <description>Persistence context for the web services</description>
> > <persistence-context-ref-name>persistence/localindexes</persistence-context-ref-name>
> > <persistence-unit-name>localindexes</persistence-unit-name>
> > </persistence-context-ref>
> >
> >
> >
> > in the web.xml or annotating the ws class with
> > @PersistenceContext(name = "persistence/localindexes", unitName =
> > "localindexes") does not help at all.
> >
> > I'm already tearing my hair out so any help would be appreciated.
> > Thanks in advance.
> >
> > my persistence.xml uses toplink as a persistence provider:
> >
> > <persistence-unit name="localindexes" transaction-type="JTA">
> > <provider>oracle.toplink.essentials.PersistenceProvider</provider>
> > <jta-data-source>mysql-localhost</jta-data-source>
> > <exclude-unlisted-classes>false</exclude-unlisted-classes>
> > <properties>
> > <property name="toplink.ddl-generation" value="create-tables"/>
> > </properties>
> > </persistence-unit>
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> > For additional commands, e-mail: users-help_at_jersey.dev.java.net
> >
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>
>