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
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.
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!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With