2012-01-06 84 views
9

Uso de JPA con la implementación de EclipseLink.JPA Ninguna transacción está actualmente activa

Código:

try{ 
    if(!em.getTransaction().isActive()) 
     em.getTransaction().begin(); 
    System.out.println(2); 
    em.persist(currentUser); 
    System.out.println(3); 
    if (em.getTransaction().isActive()){ 
     System.out.println("IS ACTIVE"); 
    } else { 
     System.out.println("NO ACTIVE"); 
    } 
    em.getTransaction().commit(); 
    System.out.println(4); 
    } catch (Exception e){ 
    completed = false; 
    em.getTransaction().rollback(); 
    System.out.println("ERROR: " + e.getMessage()); 
} 

error:

INFO: persistOne - Enter 
INFO: 2 
INFO: 3 
INFO: IS ACTIVE 
INFO: [EL Warning]: 2012-01-06 14:45:59.221--UnitOfWork(12492659)--java.lang.IllegalStateException: During synchronization a new object was found through a relationship that was not marked cascade PERSIST: [email protected] 

WARNING: #{accountController.performRegister}: java.lang.IllegalStateException: 
Exception Description: No transaction is currently active 
javax.faces.FacesException: #{accountController.performRegister}: java.lang.IllegalStateException: 
Exception Description: No transaction is currently active 
    at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:118) 
    at javax.faces.component.UICommand.broadcast(UICommand.java:315) 
    at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794) 
    at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1259) 
    at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81) 
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) 
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118) 
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593) 
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1539) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175) 
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655) 
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595) 
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:98) 
    at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:91) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:162) 
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:330) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231) 
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:174) 
    at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:828) 
    at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:725) 
    at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1019) 
    at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225) 
    at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137) 
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104) 
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90) 
    at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79) 
    at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54) 
    at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59) 
    at com.sun.grizzly.ContextTask.run(ContextTask.java:71) 
    at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532) 
    at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513) 
    at java.lang.Thread.run(Thread.java:662) 
Caused by: javax.faces.el.EvaluationException: java.lang.IllegalStateException: 
Exception Description: No transaction is currently active 
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:102) 
    at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102) 
    ... 32 more 
Caused by: java.lang.IllegalStateException: 
Exception Description: No transaction is currently active 
    at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.rollback(EntityTransactionImpl.java:122) 
    at com.maze.service.UserService.persistOne(UserService.java:63) 
    at com.maze.controller.request.AccountController.performRegister(AccountController.java:62) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at java.lang.reflect.Method.invoke(Method.java:597) 
    at com.sun.el.parser.AstValue.invoke(AstValue.java:234) 
    at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:297) 
    at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105) 
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88) 
    ... 33 more 

Lo extraño es que la transacción está activo pero lo siguiente que ocurre es un error de inactividad.

EDITAR EntityManager Singleton: public class {EntityManagerSingleton

private EntityManagerSingleton(){ 
} 

private static class EMSingletonHolder{ 
    private static final EntityManagerFactory emf = Persistence.createEntityManagerFactory("Maze"); 
    private static final EntityManager em = emf.createEntityManager(); 
} 

public static EntityManager getInstance(){ 
    return EMSingletonHolder.em; 
} 

* Obtener la Instancia em: *

public abstract class AbstractService { 
protected EntityManager em; 

public AbstractService(){ 
    em = EntityManagerSingleton.getInstance(); 
} 
} 

Todos los demás servicios se extiende la AbstractService

+0

Me gustaría prestar atención a esto - 'Durante la sincronización se ha encontrado un nuevo objeto a través de una relación que no estaba marcado PERSIST' cascada. – Perception

Respuesta

5

A juzgar por su registro, está utilizando GlassFish. Supongo que también estás usando JTA. ¿Tal vez también puede proporcionar el código que obtiene la instancia de EntityManager? Además, la depuración con declaraciones System.out es algo del pasado, use un depurador, de lo contrario, su código es difícil de leer. Además, tu sangría es incorrecta.

En primer lugar, si usted está usando JTA, echar un vistazo a esta pregunta:

EJBException when calling entityManager.getTransaction()

Presupuesto de la respuesta aceptada:

It is illegal to obtain a reference to the EntityTransaction instance associated with the EntityManager in a Java EE managed context. From the Java EE API documentation of EntityManager.getTransaction():

Return the resource-level EntityTransaction object. The EntityTransaction instance may be used serially to begin and commit multiple transactions.

Returns: 
    EntityTransaction instance Throws: 
    IllegalStateException - if invoked on a JTA entity manager 

Por eso, si espera alguna ayuda, es importante proporcionar información sobre el código/inyección a través del cual obtiene el administrador de la entidad.

Además, por el bien de la legibilidad del código, no debería tener múltiples llamadas a em.getTransaction(); Debe asignar la primera llamada a un objeto de transacción y volver a utilizarlo, un poco como esto:

//GOOD cause readable 
EntityTransaction tx = em.getTransaction(); 
tx.begin(); 
em.persist(someObject); 
tx.commit(); 

y no

//BAD cause hard to read 
em.getTransaction().begin(); 
em.persist(someObject); 
em.getTransaction().commit(); //NO! 
+0

Estoy usando resource_local no JTA – TGM

+0

El último punto de su publicación parece estar mal en el contexto de los administradores de entidades locales de recursos. No hay ninguna razón para no llamar a getTransaction varias veces para obtener la transacción actual. EntityManager tiene un único subproceso y la especificación muestra explícitamente un ejemplo que lo hace de esta manera. – chromanoid

+0

@chromanoid Me refiero a términos de legibilidad de código. Considere que necesita persistir 4 objetos más. ¿Llamarías 'em.getTransaction(). Persist (algúnObjeto)' 4 veces más? ¿O preferirías 'tx.persist (someObject)'? En el primer enfoque, cada una de las líneas se leería como hacer 2 acciones: obtener la transacción, persistir el objeto. Si bien, en realidad, lo que quieres decir es "persistir el objeto". –

1

Si nos fijamos en la última de estas trazas de la pila, veo

at org.eclipse.persistence.internal.jpa.transaction.EntityTransactionImpl.rollback(EntityTransactionImpl.java:122) 

Es un error durante la retrotracción, no durante la confirmación. Me pregunto si esto está relacionado con la advertencia sobre el objeto no persistente; algo va mal al final de la confirmación, de modo que su estructura intenta una reversión en un punto en el que es demasiado tarde para hacerlo. Apuesto a que si registró correctamente ese objeto UserDetail, el problema desaparecería.

8

Tenga en cuenta que la última excepción se produce en rollback() en el bloque catch.

Así, commit() desencadena la siguiente excepción:

java.lang.IllegalStateException: During synchronization a new object was found through a relationship that was not marked cascade PERSIST: [email protected]

Esa excepción provoca una reversión implícita, por lo que el manual rollback() en el bloque catch tiros otra excepción debido a la transacción inactivo.

Para una limpieza manual confiable, debe verificar si la transacción está activa antes de llamar al rollback() en el bloque catch también.

3

Bueno, sus registros explican, durante la confirmación, que Eclipselink recibió una excepción y revertió su transacción. Es por eso que su transation ya no está activa ..

INFO: [EL Warning]: 2012-01-06 14:45:59.221--UnitOfWork(12492659)--java.lang.IllegalStateException: During synchronization a new object was found through a relationship that was not marked cascade PERSIST: [email protected]

Cuestiones relacionadas