Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPA No transaction is currently active

Using JPA with EclipseLink implementation.

Code:

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: com.maze.model.UserDetail@d52ea.

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

The weird thing is that the Transaction is active but the next thing happening is an error of inactivity.

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

*Getting the em Instance: *

public abstract class AbstractService {
protected EntityManager em;

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

All other services extends the AbstractService

like image 804
TGM Avatar asked Jan 06 '12 12:01

TGM


2 Answers

Note that the last exception is thrown by rollback() in the catch block.

So, commit() throws the following exception:

java.lang.IllegalStateException: During synchronization a new object was found through a relationship that was not marked cascade PERSIST: com.maze.model.UserDetail@d52ea.

That exception causes an implicit rollback, so that the manual rollback() in the catch block throws another exception due to inactive transaction.

For reliable manual cleanup you need to check whether transaction is active before calling rollback() in the catch block as well.

like image 119
axtavt Avatar answered Sep 24 '22 17:09

axtavt


Judging by your log, you are using GlassFish. I assume you are also using JTA. Maybe you can provide also the code that obtains the EntityManager instance? Also, debugging with System.out statements is something from the past, use a debugger, otherwise your code is hard to read. In addition, your indentation is wrong.

First of all, if you are using JTA, take a look at this question:

EJBException when calling entityManager.getTransaction()

Quote from the accepted answer:

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

That is why if you expect any help it is important to provide information about the code/injection through which you obtain the entity manager.

Also, for the sake of code readability, you should not have multiple calls to em.getTransaction(); You should assign your first call to a Transaction object and reuse it, kinda like this:

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

and not

 //BAD cause hard to read
 em.getTransaction().begin();
 em.persist(someObject);
 em.getTransaction().commit(); //NO!
like image 7
Nikola Yovchev Avatar answered Sep 21 '22 17:09

Nikola Yovchev