How to prevent "Local transaction already has 1 non-XA Resource" exception?
I'm using 2 PU in stateless EJB and each of them is invoked on one method:
@PersistenceContext(unitName="PU")
private EntityManager em;
@PersistenceContext(unitName="PU2")
private EntityManager em2;
@TransactionAttrib开发者_如何学Cute(TransactionAttributeType.REQUIRES_NEW )
public void getCandidates(final Integer eventId) throws ControllerException {
ElectionEvent electionEvent = em.find(ElectionEvent.class, eventId);
...
Person person = getPerson(candidate.getLogin());
...
}
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW )
private Person getPerson(String login) throws ControllerException {
Person person = em2.find(Person.class, login);
return person;
}
Those methods are annotated with REQUIRES_NEW transcaction to avoid this exception. When I was calling these method from javaFX applet, all worked as expected. Now I'm trying to call them from JAX-RS webservice (I don't see any logical difference as in both cases ejb was looked up in initial context) and I keep getting this exception. When I set up XADatasource in glassfish 2.1 connection pools, I got nullpointer exception on em2.
Any ideas what to try next?
Regards
Ok,
it's solved now. I'll share just in case somebody got tackled by similar thing. Whole problem was with netbeans deploying. They overwrite the settings in glassfish connection pool and when you set them proper at runtime, you got npe's or missing password silly stuff. The place to edit this is sun-resources.xml. XML element has attributes datasource-classname and rs-type. What needs to be done in case of Derby database is:
<jdbc-connection-pool ...
datasource-classname="org.apache.derby.jdbc.ClientXADataSource"
res-type="javax.sql.XADataSource">
...
</jdbc-connection-pool>
Works like a charm now.
I'm using 2 PU in stateless EJB and each of them is invoked on one method
Indeed. But you're calling the second method from the first one so you're doing a distributed transaction and you need to use XA for this (at least for one of the resource since GlassFish supports the last agent optimization allowing to involve one non-XA resource). In other words, setting one of your datasource as a XADataSource
is the way to go.
If you get an error when doing this, please add details about what you did exactly and the stacktrace.
When calling the second method from the first, it is not an EJB method call. It treats it as just a regular method call and does not look at @TransactionAttribute
. If you want a call to the same EJB, you can inject the SessionContext
and call getBusinessObject
. Then call the method on the returned EJB.
精彩评论