query example ejemplo create consultas jpa transactions eclipselink

example - JPA/EclipseLink: ¿EntityManager.getTransaction() crea una nueva transacción o devuelve la activa?



jpa select example (3)

Estoy usando EclipseLink 2.3.0. Tengo un método al que llamo desde una prueba unitaria (por lo tanto, fuera de un contenedor, sin JTA) que se ve así:

EntityManager em = /* get an entity manager */; em.getTransaction().begin(); // make some changes em.getTransaction().commit();

Los cambios NO se conservaban en la base de datos, lo observaron durante mucho tiempo y finalmente se dieron cuenta de que EntityManager.getTransaction () en realidad está devolviendo una NUEVA EntityTransaction, en lugar de la misma en ambas llamadas. El efecto es que la primera llamada crea una nueva transacción y comienza, y la segunda convoca a crear OTRA transacción y la compromete. Como la primera transacción nunca se realizó, los cambios no se guardan. Verificamos esto de esta manera:

log.info(em.getTransaction().toString()); log.info(em.getTransaction().toString());

Lo que resultó en estos mensajes de registro:

INFO: org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl@1e34f445 INFO: org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl@706a4d1a

Los dos ID de objeto diferentes verifican que hay dos instancias diferentes. Cambiando el código a esto:

EntityManager em = /* get an entity manager */; EntityTransaction tx = em.getTransaction(); tx.begin(); // make some changes tx.commit();

... remediado el problema. Ahora cuando ejecuto el código, veo las declaraciones SQL generadas para hacer que la base de datos funcione, y al buscar en la base de datos, los datos han sido cambiados.

Me sorprendió un poco este resultado, ya que he visto numerosos ejemplos de código en línea (para JPA en general y para EclipseLink específicamente) que recomiendan el código que usamos para administrar transacciones. Busqué en todas partes información específica sobre esto, pero no he encontrado nada. Entonces, ¿qué está pasando?

Busqué en la especificación de JPA algo que especifique exactamente qué hace getTransaction () y no era específico si la transacción es nueva o la misma. ¿Hay alguna configuración en persistence.xml que controle esto? ¿Es el comportamiento específico de cada implementación de la especificación JPA?

Muchas gracias por cualquier información u orientación.


¿Has intentado usar persist antes de confirmar :?

Employee employee = new Employee("Samuel", "Joseph", "Wurzelbacher"); em.getTransaction().begin(); em.persist(employee); em.getTransaction().commit();


La especificación de JPA (consulte el párrafo 7.5.4) tiene ejemplos explícitos que muestran el uso de getTransaction() para comenzar y confirmar la transacción. Entonces tu código debería estar bien.

Su prueba muestra que obtiene dos objetos diferentes, pero eso no significa que no se use la misma transacción. Tal vez el objeto devuelto sea solo un proxy para un solo objeto de transacción real.

O tal vez la transacción se haya comprometido o revertido dentro del código oculto en // make some changes .


El uso de getTransaction () funciona en JPA y en EclipseLink (así es como funcionan nuestras propias pruebas).

Supongo que estás haciendo algo muy extraño.

¿Estás usando Spring u otra capa? Por favor incluya el código completo y persistence.xml para su prueba. Asegúrese de no estar utilizando JTA en su persistence.xml.