3 Replies Latest reply: Apr 27, 2013 3:45 AM by Krisv W RSS

org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)

Krisv W Newbie

Hi,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.

 

     task.png

 

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