cancel
Showing results for 
Search instead for 
Did you mean: 

Activiti JavaDelegate, JPA and JTA best practice

chris_joelly
Champ in-the-making
Champ in-the-making
Hello,

i want to create/query entities using JPA in an JavaDelegate
and i have Activiti configured to use JTA and a datasource
from Glassfish 3.1.1.

Within a JavaDelegate serviceTask I lookup the EntityManager
using JNDI and use this entity manager for my entity. Then i
set the entity as process variable and can use this entity in
another JavaDelegate instance in another serviceTask.
So far so good.

But i face transaction issues sometimes and i dont know how
to solve it. First i dispatch to the start form (formKey is a
JSF file) and when posting this form i create a process instance
and set the form fields as process variables. Then two service
tasks are triggered, one after each other. The first creates
a JPA entity and i set it as process variable too. Then, in the
second service task, i use all variables sucessfully and update
a field in the JPA entity. Meanwhilest another JSF view is
rendered and this JSF backing view uses the Activiti task service
to get all tasks for a candidate group. But sometimes Activiti
throws an exception. But not always. If i debug the code
of the service tasks then no exceptiion is thrown.


javax.el.ELException: /faces/owntasklist.xhtml @23,96 value="#{taskList.ownTasks}": org.apache.ibatis.exceptions.PersistenceException:
### Error opening session.  Cause: java.sql.SQLException: Error in allocating a connection. Cause: java.lang.RuntimeException: Got exception during XAResource.start:
### Cause: java.sql.SQLException: Error in allocating a connection. Cause: java.lang.RuntimeException: Got exception during XAResource.start:
   at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:114)
   at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194)
   at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:182)
   at javax.faces.component.UIData.getValue(UIData.java:731)
   at javax.faces.component.UIData.getDataModel(UIData.java:1798)
   at javax.faces.component.UIData.getRowCount(UIData.java:356)
   at org.primefaces.component.datatable.DataTable.calculatePage(DataTable.java:767)
   at org.primefaces.component.datatable.DataTableRenderer.encodeMarkup(DataTableRenderer.java:157)
   at org.primefaces.component.datatable.DataTableRenderer.encodeEnd(DataTableRenderer.java:82)
   at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:875)
   at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1763)
   at javax.faces.render.Renderer.encodeChildren(Renderer.java:168)
   at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:845)
   at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:304)
   at com.sun.faces.renderkit.html_basic.GroupRenderer.encodeChildren(GroupRenderer.java:105)
   at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:845)
   at com.sun.faces.renderkit.html_basic.HtmlBasicRenderer.encodeRecursive(HtmlBasicRenderer.java:304)
   at com.sun.faces.renderkit.html_basic.GridRenderer.renderRow(GridRenderer.java:185)
   at com.sun.faces.renderkit.html_basic.GridRenderer.encodeChildren(GridRenderer.java:129)
   at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:845)
   at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1756)
   at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1759)
   at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1759)
   at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:401)
   at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:131)
   at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:288)
   at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121)
   at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
   at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
   at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594)
   at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1539)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:343)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
   at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:79)
   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
   at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279)
   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: org.apache.ibatis.exceptions.PersistenceException:
### Error opening session.  Cause: java.sql.SQLException: Error in allocating a connection. Cause: java.lang.RuntimeException: Got exception during XAResource.start:
### Cause: java.sql.SQLException: Error in allocating a connection. Cause: java.lang.RuntimeException: Got exception during XAResource.start:
   at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:8)
   at org.apache.ibatis.session.defaults.DefaultSqlSessionFactory.openSessionFromDataSource(DefaultSqlSessionFactory.java:81)
   at org.apache.ibatis.session.defaults.DefaultSqlSessionFactory.openSession(DefaultSqlSessionFactory.java:32)
   at org.activiti.engine.impl.db.DbSqlSession.<init>(DbSqlSession.java:84)
   at org.activiti.engine.impl.db.DbSqlSessionFactory.openSession(DbSqlSessionFactory.java:77)
   at org.activiti.engine.impl.interceptor.CommandContext.getSession(CommandContext.java:177)
   at org.activiti.engine.impl.persistence.AbstractManager.getSession(AbstractManager.java:56)
   at org.activiti.engine.impl.persistence.AbstractManager.getDbSqlSession(AbstractManager.java:52)
   at org.activiti.engine.impl.persistence.entity.TaskManager.findTasksByQueryCriteria(TaskManager.java:89)
   at org.activiti.engine.impl.TaskQueryImpl.executeList(TaskQueryImpl.java:333)
   at org.activiti.engine.impl.AbstractQuery.execute(AbstractQuery.java:135)
   at org.activiti.engine.impl.interceptor.CommandExecutorImpl.execute(CommandExecutorImpl.java:24)
   at org.activiti.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:42)
   at org.activiti.engine.impl.interceptor.JtaTransactionInterceptor.execute(JtaTransactionInterceptor.java:59)
   at org.activiti.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:33)
   at org.activiti.engine.impl.AbstractQuery.list(AbstractQuery.java:109)
   at erp.web.faces.beans.activiti.TaskList.getOwnTasks(TaskList.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)

So, my question: what is the best practise to use JPA entities within service tasks and Activiti
using the same datasource, configured as JTA datasource in persistence.xml and looked up
via JNDI in activiti.cfg.xml? i think those two things bites each other but i dont know how to
solve it…

Thanks in advance

Chris
4 REPLIES 4

jbarrez
Star Contributor
Star Contributor
It should basically work, the way you describe it.
Is there any chance you could wrap it up in a simple unit test so I can test it myself?

chris_joelly
Champ in-the-making
Champ in-the-making
i am working on a unit test which deploys the ejb and war to a glassfish-embedded
and i hope i can simulate this behavior. but at the moment i have issues getting
glassfish-embedded to work. only test the Activiti will not be the same scenario.

chris_joelly
Champ in-the-making
Champ in-the-making
I think i found my problem. If i put a UserTransaction around the Activiti calls
then i can avoid these exceptions, the UserTransaction utx is injeced via
@Resource into the @ManagedBean:

    utx.begin();
    List<Task> tasks = activiti.getProcessEngine().getTaskService()
        .createTaskQuery()
        .taskAssignee(userSession.getUser().getUsername())
        .orderByTaskCreateTime().asc().list();
    utx.commit();
So: i need to start and end a transaction if i call Activiti services in an Bean
outside of an EJB and i dont need to do it if i use Activiti services within an EJB
if i use transactionsExternallyManaged = true. Btw. if i use transactionsExternallyManaged
set to false it works too.

But what i even dont understand is are the cfg options jpaPersistenceUnitName,
jpaHandleTransaction and jpaCloseEntityManager. When do i need these parameters?
Dont they interfer with a JTA setup?

frederikherema1
Star Contributor
Star Contributor
The JPA-configurations you only need when you want to use JPA-entities as process-variables in your processes. If you're just using JPA alongside your process (calling your own services from the process for example), it's not needed.