2010-04-21 8 views
6

Sto utilizzando 2 PU in EJB stateless e ciascuno di essi viene invocato su un metodo:Come impedire che "La transazione locale abbia già un'eccezione 1 Risorsa non XA"?

@PersistenceContext(unitName="PU") 
private EntityManager em; 
@PersistenceContext(unitName="PU2") 
private EntityManager em2; 

@TransactionAttribute(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; 
} 

Tali metodi sono annotati con REQUIRES_NEW transcaction per evitare questa eccezione. Quando chiamavo questo metodo dall'applet javaFX, tutto funzionava come previsto. Ora sto provando a chiamarli dal webservice JAX-RS (non vedo alcuna differenza logica in quanto in entrambi i casi ejb è stato consultato nel contesto iniziale) e continuo a ricevere questa eccezione. Quando ho impostato XADatasource nei pool di connessione 2.1 glassfish, ho ricevuto un'eccezione nullpointer su em2.

Qualche idea su cosa provare dopo?

saluti

+0

Vedere anche http://stackoverflow.com/questions/2413911/if-i-access-usertransaction-does-this-mean-that-i-use-2-phase-commit-or-xa/2425585#2425585 – ewernli

risposta

5

Ok,

è risolto ora. Condividerò nel caso qualcuno sia stato affrontato da qualcosa di simile. L'intero problema era con la distribuzione di netbeans. Sovrascrivono le impostazioni nel pool di connessione glassfish e quando le si impostano correttamente in fase di runtime, si ottengono le cose stupide di npe o mancanti. Il posto per modificare questo è sun-resources.xml. L'elemento XML ha attributi datasource-classname e rs-type. Ciò che deve essere fatto in caso di database Derby è:

<jdbc-connection-pool ... 
     datasource-classname="org.apache.derby.jdbc.ClientXADataSource" 
     res-type="javax.sql.XADataSource"> 
    ... 
</jdbc-connection-pool> 

funziona come un fascino ora.

2

sto usando 2 PU in EJB stateless e ciascuno di essi è invocato su un metodo

davvero. Ma stai chiamando il secondo metodo dal primo in modo da eseguire una transazione distribuita e devi usare XA per questo (almeno per una delle risorse poiché GlassFish supporta lo last agent optimization che consente di coinvolgere una risorsa non XA) . In altre parole, l'impostazione di una fonte di dati come XADataSource è la strada da percorrere.

Se si verifica un errore durante questa operazione, aggiungere dettagli su ciò che è stato fatto esattamente e lo stacktrace.

+0

Grazie, lo posterò al più presto, ma nel medio, c'è un modo per specificare XADataSource in persistence.xml? Non l'ho trovato da nessuna parte e ogni volta che utilizzo tramite netbeans l'impostazione glassfish nel pool di connessione viene ripristinata su semplice DataSource. – zeratul021

1

Quando si chiama il secondo metodo dal primo, non si tratta di una chiamata al metodo EJB. Lo considera come una normale chiamata di metodo e non guarda a @TransactionAttribute. Se si desidera una chiamata allo stesso EJB, è possibile iniettare lo SessionContext e chiamare getBusinessObject. Quindi chiama il metodo sul bean restituito.