org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)
gang2007 Apr 26, 2013 1:16 AMHi,everybody!
I have a process with two User Task Nodes. When completing the first one by excuting “client.complete(taskId, userId, contentData);”, the console shows as follows. But it has been completed and also the second one has been started as shown in the database table Task . From the console info, it seems the reason is that anther transaction has updated the record of ProcessInstanceInfo. But I do not know what it is, who can tell me? Any idea how to fix it? Please help
Thanks in advance for any help.
Exception in thread "Thread-42" java.lang.RuntimeException: Unable to commit transaction
at org.drools.persistence.jta.JtaTransactionManager.commit(JtaTransactionManager.java:182)
at org.drools.persistence.SingleSessionCommandService.execute(SingleSessionCommandService.java:371)
at org.drools.command.impl.CommandBasedStatefulKnowledgeSession$1.completeWorkItem(CommandBasedStatefulKnowledgeSession.java:150)
at org.jbpm.process.workitem.wsht.GenericHTWorkItemHandler$TaskCompletedHandler.handleCompletedTask(GenericHTWorkItemHandler.java:219)
at org.jbpm.process.workitem.wsht.GenericHTWorkItemHandler$TaskCompletedHandler$1.run(GenericHTWorkItemHandler.java:187)
at java.lang.Thread.run(Thread.java:619)
Caused by: javax.persistence.OptimisticLockException: org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [org.jbpm.persistence.processinstance.ProcessInstanceInfo#1]
at org.hibernate.ejb.AbstractEntityManagerImpl.wrapStaleStateException(AbstractEntityManagerImpl.java:630)
at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:588)
at org.hibernate.ejb.AbstractEntityManagerImpl$1.beforeCompletion(AbstractEntityManagerImpl.java:513)
at bitronix.tm.BitronixTransaction.fireBeforeCompletionEvent(BitronixTransaction.java:478)
at bitronix.tm.BitronixTransaction.commit(BitronixTransaction.java:193)
at bitronix.tm.BitronixTransactionManager.commit(BitronixTransactionManager.java:120)
at org.drools.persistence.jta.JtaTransactionManager.commit(JtaTransactionManager.java:179)
... 5 more
Caused by: org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [org.jbpm.persistence.processinstance.ProcessInstanceInfo#1]
at org.hibernate.persister.entity.AbstractEntityPersister.check(AbstractEntityPersister.java:1782)
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2425)
at org.hibernate.persister.entity.AbstractEntityPersister.updateOrInsert(AbstractEntityPersister.java:2325)
at org.hibernate.persister.entity.AbstractEntityPersister.update(AbstractEntityPersister.java:2625)
at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:115)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:168)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1028)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:366)
at org.hibernate.ejb.AbstractEntityManagerImpl$1.beforeCompletion(AbstractEntityManagerImpl.java:504)
... 9 more
Task table is shown as follows. We can see the first one has been completed while the second one Reserved.
The following is the servlet which invokes the task node complete method when completing operation is triggered. And the line "JbpmAPIUtil.completeTask(client,taskId, data, user, minaHTWorkItemHandler);
"is where exception happens. I have tried to catch it, but failed. What a strange thing!
public class TaskProcessServlet extends HttpServlet { private StatefulKnowledgeSession ksession = null; private MinaHTWorkItemHandler minaHTWorkItemHandler = null; private TaskService client = null; private JPAWorkingMemoryDbLogger dblogger = null; @Override public void init() throws ServletException { super.init(); try { ksession = JbpmAPIUtil.getSession(); minaHTWorkItemHandler = new MinaHTWorkItemHandler(ksession); ksession.getWorkItemManager().registerWorkItemHandler("Human Task", minaHTWorkItemHandler); minaHTWorkItemHandler.connect(); dblogger = new JPAWorkingMemoryDbLogger( ksession); SystemEventListenerFactory .setSystemEventListener(new SystemEventListener()); client = new SyncTaskServiceWrapper(new AsyncMinaTaskClient()); boolean connected = client.connect("127.0.0.1", 9123); if (!connected) { throw new IllegalArgumentException( "Could not connect task client"); } } catch (Throwable t) { throw new RuntimeException("error while creating session", t); } } protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); try { String action = request.getParameter("action"); if (action.equals("Submit")) { String user = request.getParameter("user"); Map<String,String> data = new HashMap<String,String>(); data.put("priority", request.getParameter("priority")); data.put("modelNumber", request.getParameter("modelNumber")); data.put("quantity", request.getParameter("quantity")); long taskId = new Long(request.getParameter("taskId")) .longValue(); String taskStatus = request.getParameter("taskStatus"); if (!taskStatus.equals("Completed")) JbpmAPIUtil.completeTask(client,taskId, data, user, minaHTWorkItemHandler); RequestDispatcher rD = request .getRequestDispatcher("index.jsp"); rD.forward(request, response); } } catch (Exception e) { out.println("Error:" + e.getMessage().toString()); } finally { out.close(); } } @Override public void destroy() { super.destroy(); dblogger.dispose(); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } ...... }
The following is the completeTask method of JbpmAPIUtil.java.
public static void completeTask(TaskService client, long taskId, Map data, String userId, MinaHTWorkItemHandler minaHTWorkItemHandler) throws InterruptedException { client.start(taskId, userId); Thread.sleep(10000); ContentData contentData = ContentMarshallerHelper.marshal(data, minaHTWorkItemHandler.getMarshallerContext(), null); client.complete(taskId, userId, contentData); Thread.sleep(2000); }