2012-01-06 9 views
9

Utilizzo di JPA con implementazione EclipseLink.JPA Nessuna transazione è attualmente attiva

Codice:

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()); 
} 

Errore:

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 

La cosa strana è che la transazione è attiva, ma la prossima cosa succede è un errore di inattività.

EDIT 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; 
} 

* Ottenere il grado em: *

public abstract class AbstractService { 
protected EntityManager em; 

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

Tutti gli altri servizi si estende l'AbstractService

+0

Farei attenzione a questo: 'Durante la sincronizzazione è stato trovato un nuovo oggetto attraverso una relazione che non è stata contrassegnata in cascata PERSIST'. – Perception

risposta

5

A giudicare dal tuo registro, stai usando GlassFish. Presumo che tu stia usando anche JTA. Forse puoi fornire anche il codice che ottiene l'istanza EntityManager? Inoltre, il debugging con le istruzioni System.out è qualcosa del passato, usa un debugger, altrimenti il ​​tuo codice è difficile da leggere. Inoltre, il tuo rientro è sbagliato.

Prima di tutto, se si utilizza JTA, dare un'occhiata a questa domanda:

EJBException when calling entityManager.getTransaction()

Citazione dalla risposta accettata:

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 

Ecco perché se ci si aspetta aiuto è importante fornire informazioni sul codice/iniezione attraverso il quale si ottiene il gestore dell'entità.

Inoltre, per motivi di leggibilità del codice, non è necessario avere più chiamate a em.getTransaction(); È necessario assegnare la prima chiamata a un oggetto di transazione e riutilizzarlo, un po 'come questo:

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

e non

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

Sto usando resource_local non JTA – TGM

+0

L'ultimo punto del tuo post sembra essere sbagliato nel contesto dei gestori di entità locali delle risorse. Non vi è alcun motivo per non chiamare getTransaction più volte per ottenere la transazione corrente. EntityManager è a thread singolo e la specifica mostra esplicitamente un esempio che esegue in questo modo. – chromanoid

+0

@chromanoid I stava intendendo termini di leggibilità del codice. Considera che devi mantenere altri 4 oggetti. Chiameresti "em.getTransaction(). Persist (someObject)" altre 4 volte? O preferiresti "tx.persist (someObject)"? Nel primo approccio ognuna delle righe dovrebbe leggere come fare 2 azioni: ottenere la transazione, mantenere l'oggetto. Mentre in realtà quello che vuoi dire è "persist l'oggetto". –

1

Se si guarda l'ultimo di questi stack, vedo

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

È un errore durante il rollback, non durante il commit. Mi chiedo se questo è legato all'avvertimento sull'oggetto non contemplato; qualcosa va storto alla fine del commit in modo tale che il tuo framework tenti un rollback in un punto in cui è troppo tardi per farlo. Scommetto che se hai registrato correttamente l'oggetto UserDetail, il problema si risolverebbe.

8

Si noti che l'ultima eccezione viene generata da rollback() nel blocco catch.

Quindi, commit() genera la seguente eccezione:

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

Tale eccezione provoca un rollback implicito, in modo che il manuale rollback() nel blocco catch tiri un'altra eccezione a causa di transazioni inattive.

Per una pulizia manuale affidabile è necessario verificare se la transazione è attiva prima di chiamare rollback() anche nel blocco di cattura.

3

Bene, i registri spiegano, durante il commit, Eclipselink ha ottenuto un'eccezione e il rollback della transazione. Questo è il motivo per cui la tua transizione non è più attiva ..

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]

Problemi correlati