please help org.camunda.bpm.engine.OptimisticLockingException: By Calling "identityService.saveUser(camundaUserEntity)"

130 views
Skip to first unread message

marcel...@gmail.com

unread,
Nov 6, 2014, 5:27:29 PM11/6/14
to camunda-...@googlegroups.com
I use a spring Application, Hibernate and JSF for my process application on Tomcat. I inject the Camunda Spring Bean IdentityService in my own Spring Bean UserServicem which have the folowing method:


public void saveUserAndMembership(User user){


//TransactionStatus status=transactionManager.getTransaction(null);

try{

// Save The User Entity in Camunda Table User Entity
UserEntity camundaUserEntity= user.getUserEntity();
identityService.saveUser(camundaUserEntity);

//transactionManager.commit(status);

}
catch(RuntimeException e){
//transactionManager.rollback(status);
throw e;
}

}


when the method is called. I get a exception:

javax.faces.el.EvaluationException: org.camunda.bpm.engine.OptimisticLockingException: UserEntity[kjkjlkjl] was updated by another transaction concurrently
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:102)
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:101)
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.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.myfaces.webapp.filter.ExtensionsFilter.doFilter(ExtensionsFilter.java:357)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:409)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1044)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:315)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Caused by: org.camunda.bpm.engine.OptimisticLockingException: UserEntity[kjkjlkjl] was updated by another transaction concurrently
at org.camunda.bpm.engine.impl.db.DbSqlSession.flushUpdates(DbSqlSession.java:692)
at org.camunda.bpm.engine.impl.db.DbSqlSession.flush(DbSqlSession.java:488)
at org.camunda.bpm.engine.impl.interceptor.CommandContext.flushSessions(CommandContext.java:196)
at org.camunda.bpm.engine.impl.interceptor.CommandContext.close(CommandContext.java:126)
at org.camunda.bpm.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:99)
at org.camunda.bpm.engine.spring.SpringTransactionInterceptor$1.doInTransaction(SpringTransactionInterceptor.java:42)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:130)
at org.camunda.bpm.engine.spring.SpringTransactionInterceptor.execute(SpringTransactionInterceptor.java:40)
at org.camunda.bpm.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:32)
at org.camunda.bpm.engine.impl.IdentityServiceImpl.saveUser(IdentityServiceImpl.java:75)
at com.kpmg.gbc.model.services.impl.UserServiceImpl.saveUserAndMembership(UserServiceImpl.java:269)
at com.kpmg.gbc.controller.jsfbeans.UserManagedBean.saveUserAndMembership(UserManagedBean.java:139)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.el.parser.AstValue.invoke(AstValue.java:278)
at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:274)
at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:39)
at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50)
at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)
... 30 more


There are any concurrent transactions/Actions on this table. I dont know , what i make wrong. As you see I commented the opening and Comit of the Spring transaction, beacause I Think, that a transaction during the call of the save Methode by the Camunda engine ist opened and comited.

Please can you help me.

Thanks

Marcel

Daniel Meyer

unread,
Nov 7, 2014, 3:56:12 AM11/7/14
to camunda-...@googlegroups.com, marcel...@gmail.com
Hi Marcel,

thank you for your question.

From the code snippet you provided it is a bit hard to see what you are doing.

Do you think it would be possible to provide a faling testcase?

Regards,
Daniel

marcel...@gmail.com

unread,
Nov 7, 2014, 6:32:31 AM11/7/14
to camunda-...@googlegroups.com, marcel...@gmail.com
Hi Daniel,

thank you for Replying . I solved the first problem.
But I have the impression, that the identityService does'nt save the user, group, membership in the defined engine database. the RuntimeService do that. but the IdentitySernive no..

I have folowing simple Test environment

ApplicationContext

<bean>
...

<!-- Definition of Datasource-->

<bean id="dataSource" class="org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy">
<property name="targetDataSource">
<bean class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/camundabpm" />
<property name="username" value="root" />
<property name="password" value="" />
</bean>
</property>
</bean>


<!-- Hibernate SessionFactory Definition for the application with Hibernate Properties -->

<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">

<property name="dataSource" ref="dataSource" />
<property name="packagesToScan" value="com.kpmg.gbc.model.businessobjects" />


<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.jdbc.batch_size">0</prop>
<prop key="hibernate.cglib.use_reflection_optimizer">true</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</prop>
<prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate4.SpringSessionContext</prop>
</props>
</property>
</bean>

<!-- Transactionmanager for managing the transaction on service Layer -->

<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref ="sessionFactory" />
</bean>


.....


<bean id="userService" class="com.kpmg.gbc.model.services.impl.UserServiceImpl"/>

<bean id="processEngineConfiguration" class="org.camunda.bpm.engine.spring.SpringProcessEngineConfiguration">
<property name="processEngineName" value="engine" />
<property name="dataSource" ref="dataSource" />
<property name="transactionManager" ref="transactionManager" />
<property name="databaseSchemaUpdate" value="true" />
<property name="jobExecutorActivate" value="false" />
<property name="history" value="full"/>
<property name="deploymentResources" value="classpath*:*.bpmn" />
</bean>


<bean id="processEngine" class="org.camunda.bpm.engine.spring.ProcessEngineFactoryBean">
<property name="processEngineConfiguration" ref="processEngineConfiguration" />
</bean>

<bean id="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService" />
<bean id="runtimeService" factory-bean="processEngine" factory-method="getRuntimeService" />
<bean id="taskService" factory-bean="processEngine" factory-method="getTaskService" />
<bean id="historyService" factory-bean="processEngine" factory-method="getHistoryService" />
<bean id="managementService" factory-bean="processEngine" factory-method="getManagementService" />
<bean id="identityService" factory-bean="processEngine" factory-method="getIdentityService" />
<bean id="formService" factory-bean="processEngine" factory-method="getFormService" />
<bean id="AuthorizationService" factory-bean="processEngine" factory-method="getAuthorizationService" />

</bean>


In my own Spring userService i inject the Indentityserive


@Service
public class UserServiceImpl implements UserService{


@Autowired
IdentityService identityService;


.......


public void test(){

// save User
org.camunda.bpm.engine.identity.User testUser = identityService.newUser("Nikita");
testUser.setFirstName("Nikita");
testUser.setLastName("Nikita");
testUser.setPassword("Nikita");
testUser.setEmail("de...@camunda.org");

identityService.saveUser(testUser);

// save Group
Group group = new GroupEntity();
group.setId("Test");
group.setName("Test");
group.setType("TestType");

identityService.saveGroup(group);


// save Camunda Membership
//identityService.createMembership("Nikita", "Test");

}


I get no error, when i call the method. But I can see nothing in the tables:
act_id_user, act_id_membership, act_id_group ....

I think that strange. because In a another own Service . I inject the runtimeservice and call

.....
runtimeService.startProcessInstanceByKey("AbrechnungVonStartschulungen",processVariables);
.....

I see that the process is started and the processdatas are saved in the engine database, which i have defined in my Spring Context.
I defined The Runtimeservice and Identityservice from the "processEngineConfiguration" . The runtimeservice uses the datasource of the engine and the identityservice dont use that..

Sorry for my english...

What ist wrong?

Thanks for Replying.

Marcel

Daniel Meyer

unread,
Nov 7, 2014, 6:57:15 AM11/7/14
to camunda-...@googlegroups.com, marcel...@gmail.com
Hi Marcel,

from the source code you provided I cannot immediately see what the problem is. Maybe it is related to transaction management: ie. when you look into the database to check wheter the data was saved, your transaction is not yet commited and hence you do not see the data yet?

Does the following interaction work?

User testUser = identityService.newUser("Nikita");
...
identityService
.saveUser(testUser);

assertNotNull
(identityService.createUserQuery().userId("Nikita").singleResult());

Cheers,
Daniel

marcel...@gmail.com

unread,
Nov 7, 2014, 7:20:07 AM11/7/14
to camunda-...@googlegroups.com, marcel...@gmail.com
Hi Daniel ,

thanks for Replying.

I logged, if the object is created as recommanded.

.......
identityService.saveUser(testUser);

LOGGER.info("USER +++++++++"+identityService.createUserQuery().userId("Nikita").singleResult());

In the logfile . I can see folowing line:


INFORMATION: USER +++++++++UserEntity[id=Nikita, revision=1, firstName=Nikita, lastName=Nikita, email=de...@camunda.org, password={SHA}XcdXcE2sCF2ynz6eopXotakaw8U=]

The User is created. But i Can not see the rowdata in the Table? ist the right table act_id_user? I think ist definetly a problem with the transaction. the transaction ist not yet committed. how can i see the data in the table?
wait , or there are a possibility to configure the transaction of the engine.


Thanks

Marcel
Reply all
Reply to author
Forward
0 new messages