Sto usando EclipseLink 2.3.0. Ho un metodo che sto chiamando da un test di unità (quindi al di fuori di un contenitore, non JTA) che assomiglia a questo:JPA/EclipseLink: EntityManager.getTransaction() crea una nuova transazione o restituisce quella attiva?
EntityManager em = /* get an entity manager */;
em.getTransaction().begin();
// make some changes
em.getTransaction().commit();
Le modifiche sono state non essere persistito nel database, e hanno esaminato questo per un molto tempo e finalmente si è reso conto che EntityManager.getTransaction() sta effettivamente restituendo una NUOVA EntityTransaction, piuttosto che la stessa in entrambe le chiamate. L'effetto è che la prima chiamata crea una nuova transazione e la inizia, e la seconda chiamata crea un'altra transazione e la impegna. Poiché la prima transazione non è mai stata eseguita, le modifiche non vengono salvate. Abbiamo verificato questo come questo:
log.info(em.getTransaction().toString());
log.info(em.getTransaction().toString());
che ha portato in questi messaggi di log:
INFO: org.ecl[email protected]1e34f445
INFO: org.ecl[email protected]706a4d1a
Le due verificando che ci sono due diverse istanze diverse di ID oggetto. Modifica del codice a questo:
EntityManager em = /* get an entity manager */;
EntityTransaction tx = em.getTransaction();
tx.begin();
// make some changes
tx.commit();
... risolto il problema. Ora quando eseguo il codice, vedo le istruzioni SQL generate per far funzionare il database e, guardando nel database, i dati sono stati modificati.
Sono stato un po 'sorpreso da questo risultato, dal momento che ho visto numerosi esempi di codice online (per JPA in generale e per EclipseLink in particolare) che raccomandano il codice che abbiamo usato per la gestione delle transazioni. Ho cercato in lungo e in largo per informazioni specifiche su questo ma non ho trovato nulla. Quindi cosa sta succedendo?
Ho esaminato le specifiche JPA per qualcosa che specifica esattamente cosa fa getTransaction() e non era specifico se la transazione è nuova o uguale. Esiste un'impostazione in persistence.xml che controlla questo? Il comportamento è specifico per ogni implementazione delle specifiche JPA?
Grazie mille per qualsiasi informazione o guida.
Forse avrei dovuto essere più chiaro: il codice che ho postato NON funziona. Ho apportato delle modifiche alla domanda per chiarire. –
Lo capisco. Il mio punto è che * dovrebbe * funzionare, dal momento che la specifica JPA contiene esempi di codice quando 'em.getTransaction()' è usato per iniziare e registrare la transazione. Quindi deve essere un bug in EclipseLink, a meno che, come ho detto, il codice tra l'inizio e il commit già commetta o ripristina la transazione. La mia risposta non è una soluzione al tuo problema, ma una conferma che il codice dovrebbe funzionare. Suggerisco di presentare un errore a EclipseLink. –