We are trying to implement custom task node in JBPM and ended up with a strange hibernate error.
we have two tables - Task_Instance (jBPM) and Custom_Task. Custom_Task is child table of Task_Instance
Code:
<subclass name="com.test.ags.workflow.extensions.tasks.CustomTaskInstance"
discriminator-value="A">
<join table="CUSTOM_TASK">
<key column="ID" />
<property name="personId" column="Person_id" />
</join>
</subclass>
Custom_task Table has both Id, PersonId as not-null columns defined in database.
When we try to persist an object of custom_task for the first time (create a task), it fires two queries - one to insert into Task_instance and other into Custom_Task both of which are successful.
Code:
Hibernate: insert into JBPM_TASKINSTANCE (VERSION_, NAME_, DESCRIPTION_, ACTORID_, CREATE_, START_, END_, DUEDATE_, PRIORITY_, ISCANCELLED_, ISSUSPENDED_, ISOPEN_, ISSIGNALLING_, ISBLOCKING_, TASK_, TOKEN_, PROCINST_, SWIMLANINSTANCE_, TASKMGMTINSTANCE_, CLASS_, ID_) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'A', ?)
Hibernate: insert into CUSTOM_TASK (Person_id, ID) values (?, ?)
Hibernate: update JBPM_TOKEN set VERSION_=?, NAME_=?, START_=?, END_=?, NODEENTER_=?, NEXTLOGINDEX_=?, ISABLETOREACTIVATEPARENT_=?, ISTERMINATIONIMPLICIT_=?, ISSUSPENDED_=?, LOCK_=?, NODE_=?, PROCESSINSTANCE_=?, PARENT_=?, SUBPROCESSINSTANCE_=? where ID_=? and VERSION_=?
Hibernate: update JBPM_PROCESSINSTANCE set VERSION_=?, KEY_=?, START_=?, END_=?, ISSUSPENDED_=?, PROCESSDEFINITION_=?, ROOTTOKEN_=?, SUPERPROCESSTOKEN_=? where ID_=? and VERSION_=?
Hibernate: update JBPM_MODULEINSTANCE set PROCESSINSTANCE_=?, NAME_=? where ID_=?
Hibernate: update JBPM_MODULEINSTANCE set PROCESSINSTANCE_=?, NAME_=? where ID_=?
Next when user tries to complete the task, again it fires two queries - one to Task_Instance which is successful and other to child table Custom_Task. But Hibernate does so in two steps.
Step 1 it inserts a record into the custom_task table with only the ID value set. Then it comes around and updates that row with the PERSON_ID value. The second query fails with below error (verified that the value for personid is passed correctly):
Code:
Hibernate: insert into JBPM_TASKINSTANCE (VERSION_, NAME_, DESCRIPTION_, ACTORID_, CREATE_, START_, END_, DUEDATE_, PRIORITY_, ISCANCELLED_, ISSUSPENDED_, ISOPEN_, ISSIGNALLING_, ISBLOCKING_, TASK_, TOKEN_, PROCINST_, SWIMLANINSTANCE_, TASKMGMTINSTANCE_, CLASS_, ID_) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'A', ?)
Hibernate: insert into CUSTOM_TASK (Person_id, ID) values (?, ?)
[2009-05-05 15:47:08,074] (JDBCExceptionReporter:logExceptions:77) - SQL Error: 1400, SQLState: 23000
[2009-05-05 15:47:08,090] (JDBCExceptionReporter:logExceptions:78) - ORA-01400: cannot insert NULL into ("JBPM"."CUSTOM_TASK"."Person_id")
This is of course because there is a not null constraint on the table. In the second pass it is firing an Insert statement to insert the ID for the custom_task table. It then comes around at the end and does an update to that row and adds the PERSON_ID value to it.
This statement gets executed right at the end. This only happens when one task is being completed and another one is being created.
Code:
update jbpm.CUSTOM_TASK set PERSON_ID=? where ID=?
This of course works good when the not-null constraint is removed on the table.
Environment:
JBPM 3.2.3
Hibernate: 3.2.6.ga
Link on JBPM:
http://www.jboss.org/index.html?module= ... c&t=154821