[rules-users] Setting a Flow Variable from a Rule

Todd Pagni todd.pagni at datacert.com
Mon Jan 18 15:53:57 EST 2010


Kris,
Here is some more information on the problem we are having with the last
stable build. This is a critical issue for us, so your help is
appreciated. We need the latest snapshot since we are using Human Tasks
and the latest snapshot fixes an issue where the flow was not continuing
after a workitem was completed.  

================================================
Example 1

Running a flow with rules, notice the hashcode changes for the flow
entity variable.  Both entity modifications from the rule and the flow
end up in the DB, 
just the rule modification is not visible in the flow because we are
getting a new object instance somewhere.  
================================================
14:37:38,790 INFO  [STDOUT] entity hashcode at fact insert:24120808 -
same instance passed into the flow as a variable

14:37:38,805 INFO  [STDOUT] Hibernate: insert into ProcessInstanceInfo
(externalVariables, lastModificationDate, lastReadDate, processId,
processInstanceByteArray, startDate, state, OPTLOCK) values (?, ?, ?, ?,
?, ?, ?, ?)
14:37:38,805 INFO  [STDOUT] Hibernate: update ProcessInstanceInfo set
externalVariables=?, lastModificationDate=?, lastReadDate=?,
processId=?, processInstanceByteArray=?, startDate=?, state=?, OPTLOCK=?
where processInstanceId=? and OPTLOCK=?
14:37:38,805 INFO  [STDOUT] Hibernate: insert into
ProcessInstanceInfo_eventTypes (ProcessInstanceInfo_processInstanceId,
element) values (?, ?)
14:37:38,805 INFO  [STDOUT] Hibernate: update SessionInfo set dirty=?,
lastModificationDate=?, rulesByteArray=?, startDate=? where id=?

14:37:38,821 INFO  [STDOUT] entity hashcode in rules:24120808

14:37:38,821 INFO  [STDOUT] Hibernate: select
processins0_.processInstanceId as col_0_0_ from ProcessInstanceInfo
processins0_ where ? in (select eventtypes1_.element from
ProcessInstanceInfo_eventTypes eventtypes1_ where
processins0_.processInstanceId=eventtypes1_.ProcessInstanceInfo_processI
nstanceId)
14:37:38,821 INFO  [STDOUT] Hibernate: select
processins0_.processInstanceId as processI1_292_0_,
processins0_.externalVariables as external2_292_0_,
processins0_.lastModificationDate as lastModi3_292_0_,
processins0_.lastReadDate as lastRead4_292_0_, processins0_.processId as
processId292_0_, processins0_.processInstanceByteArray as
processI6_292_0_, processins0_.startDate as startDate292_0_,
processins0_.state as state292_0_, processins0_.OPTLOCK as OPTLOCK292_0_
from ProcessInstanceInfo processins0_ where
processins0_.processInstanceId=?

14:37:38,821 INFO  [STDOUT] entity hashcode at end of flow:23470994


================================================
Example 2

Running a flow without rule execution, notice the hashcode stays the
same:
================================================
14:43:07,988 INFO  [STDOUT] entity hashcode at fact insert:28309191

14:43:08,003 INFO  [STDOUT] Hibernate: insert into ProcessInstanceInfo
(externalVariables, lastModificationDate, lastReadDate, processId,
processInstanceByteArray, startDate, state, OPTLOCK) values (?, ?, ?, ?,
?, ?, ?, ?)

14:43:08,003 INFO  [STDOUT] entity hashcode at end of flow:28309191

14:43:08,003 INFO  [STDOUT] Hibernate: delete from ProcessInstanceInfo
where processInstanceId=? and OPTLOCK=?
14:43:08,003 INFO  [STDOUT] Hibernate: select
processins0_.processInstanceId as col_0_0_ from ProcessInstanceInfo
processins0_ where ? in (select eventtypes1_.element from
ProcessInstanceInfo_eventTypes eventtypes1_ where
processins0_.processInstanceId=eventtypes1_.ProcessInstanceInfo_processI
nstanceId)
14:43:08,003 INFO  [STDOUT] Hibernate: update SessionInfo set dirty=?,
lastModificationDate=?, rulesByteArray=?, startDate=? where id=?

-----Original Message-----
From: Todd Pagni 
Sent: Monday, January 18, 2010 7:49 AM
To: 'Kris Verlaenen'; Rules Users List
Subject: RE: [rules-users] Setting a Flow Variable from a Rule

When I run the following flow in JBoss 5.1, the Person entity gets
duplicated in one of the nodes. The Person entity is a hibernate managed
object that is already persisted to the DB.  Before snapshot I would
modify the entity in the rule and read the entity value in the flow to
set the Human Task Actor.  This worked in the milestone release but no
longer works in the current snapshot.

I do not see the same behavior when running from eclipse with a non
hibernate object.  

Note: I am using a groovy Person object in my flow that is a subclass of
PersonBase().  I use the PersonBase() in my rule because the rules
engine does not register the Person object as a fact it registers the
PersonBase superclass for some reason.  This is likely a separate issue,
but I thought I would make you aware.

<?xml version="1.0" encoding="UTF-8"?> 
<process xmlns="http://drools.org/drools-5.0/process"
         xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
         xs:schemaLocation="http://drools.org/drools-5.0/process
drools-processes-5.0.xsd"
         type="RuleFlow" name="Approval Flow"
id="com.datacert.workflow.Base" package-name="com.datacert"
version="1.0" >

  <header>
    <variables>
      <variable name="entityId" >
        <type
name="org.drools.process.core.datatype.impl.type.ObjectDataType"
className="java.lang.String" />
      </variable>
      <variable name="currentApproverName" >
        <type
name="org.drools.process.core.datatype.impl.type.ObjectDataType"
className="java.lang.String" />
      </variable>
      <variable name="entity" >
        <type
name="org.drools.process.core.datatype.impl.type.ObjectDataType"
className="com.datacert.apps.sampleapplication.models.Person" />
      </variable>
    </variables>
  </header>

  <nodes>
    <ruleSet id="13" name="flight rules" x="272" y="280" width="80"
height="48" ruleFlowGroup="approval" />
    <end id="11" name="End" x="291" y="446" width="48" height="48" />
    <start id="1" name="Start" x="289" y="15" width="48" height="48" />
    <actionNode id="7" name="Read Variables" x="257" y="106" width="113"
height="48" >
        <action type="expression" dialect="mvel"
>System.out.println("********** currentApproverName:" +
currentApproverName + " airline:" + entity.getlastapprover());</action>
    </actionNode>
    <actionNode id="10" name="Read Variables" x="250" y="359"
width="131" height="48" >
        <action type="expression" dialect="mvel"
>System.out.println("**************approver:" + currentApproverName  + "
airline:" + entity.getlastapprover());</action>
    </actionNode>
    <actionNode id="12" name="Set Variables" x="257" y="195" width="112"
height="48" >
        <action type="expression" dialect="mvel"
>entity.setlastapprover("southwest");
currentApproverName="approver1";</action>
    </actionNode>
  </nodes>

  <connections>
    <connection from="12" to="13" />
    <connection from="10" to="11" />
    <connection from="1" to="7" />
    <connection from="13" to="10" />
    <connection from="7" to="12" />
  </connections>

</process>



package com.datacert

dialect "mvel"
 
import com.datacert.apps.sampleapplication.models.*;
 
rule "Initial Approval"
ruleflow-group "approval"
	when
	    $p : PersonBase()
	then
		System.out.println( "******** setting approver in
rules");
		$p.setlastapprover("delta");
		
end


Latest snapshot output - note you will see two approver: entries when
there should only be one. 

20:18:21,123 INFO  [STDOUT] Hibernate: insert into SessionInfo (dirty,
lastModificationDate, rulesByteArray, startDate) values (?, ?, ?, ?)
20:18:21,139 INFO  [STDOUT] Hibernate: insert into ProcessInstanceInfo
(externalVariables, lastModificationDate, lastReadDate, processId,
processInstanceByteArray, startDate, state, OPTLOCK) values (?, ?, ?, ?,
?, ?, ?, ?)
20:18:21,139 INFO  [STDOUT] ********** currentApproverName:null
airline:southwest
20:18:21,139 INFO  [STDOUT] Hibernate: update ProcessInstanceInfo set
externalVariables=?, lastModificationDate=?, lastReadDate=?,
processId=?, processInstanceByteArray=?, startDate=?, state=?, OPTLOCK=?
where processInstanceId=? and OPTLOCK=?
20:18:21,139 INFO  [STDOUT] Hibernate: insert into
ProcessInstanceInfo_eventTypes (ProcessInstanceInfo_processInstanceId,
element) values (?, ?)
20:18:21,139 INFO  [STDOUT] Hibernate: update SessionInfo set dirty=?,
lastModificationDate=?, rulesByteArray=?, startDate=? where id=?
20:18:21,170 INFO  [STDOUT] *** inserting:
com.datacert.apps.sampleapplication.models.Person
20:18:21,264 INFO  [STDOUT] Hibernate: update SessionInfo set dirty=?,
lastModificationDate=?, rulesByteArray=?, startDate=? where id=?
20:18:21,280 INFO  [STDOUT] ******** setting approver in rules
20:18:21,326 INFO  [STDOUT] Hibernate: select
processins0_.processInstanceId as col_0_0_ from ProcessInstanceInfo
processins0_ where ? in (select eventtypes1_.element from
ProcessInstanceInfo_eventTypes eventtypes1_ where
processins0_.processInstanceId=eventtypes1_.ProcessInstanceInfo_processI
nstanceId)
20:18:21,342 INFO  [STDOUT] Hibernate: select
processins0_.processInstanceId as processI1_344_0_,
processins0_.externalVariables as external2_344_0_,
processins0_.lastModificationDate as lastModi3_344_0_,
processins0_.lastReadDate as lastRead4_344_0_, processins0_.processId as
processId344_0_, processins0_.processInstanceByteArray as
processI6_344_0_, processins0_.startDate as startDate344_0_,
processins0_.state as state344_0_, processins0_.OPTLOCK as OPTLOCK344_0_
from ProcessInstanceInfo processins0_ where
processins0_.processInstanceId=?
20:18:21,342 INFO  [STDOUT] **************approver:null airline:delta
20:18:21,342 INFO  [STDOUT] Hibernate: select variables0_.processId as
processId1_, variables0_.id as id1_, variables0_.name as formula10_1_,
variables0_.id as id345_0_, variables0_.name as name345_0_,
variables0_.persister as persister345_0_, variables0_.entityClass as
entityCl5_345_0_, variables0_.entityId as entityId345_0_,
variables0_.content as content345_0_, variables0_.TYPE as TYPE345_0_
from VariableInstanceInfo variables0_ where variables0_.processId=?
20:18:21,342 INFO  [STDOUT] Hibernate: delete from
ProcessInstanceInfo_eventTypes where
ProcessInstanceInfo_processInstanceId=?
20:18:21,342 INFO  [STDOUT] Hibernate: delete from ProcessInstanceInfo
where processInstanceId=? and OPTLOCK=?
20:18:21,342 INFO  [STDOUT] Hibernate: select
processins0_.processInstanceId as col_0_0_ from ProcessInstanceInfo
processins0_ where ? in (select eventtypes1_.element from
ProcessInstanceInfo_eventTypes eventtypes1_ where
processins0_.processInstanceId=eventtypes1_.ProcessInstanceInfo_processI
nstanceId)
20:18:21,342 INFO  [STDOUT] **************approver:null
airline:southwest
20:18:21,342 INFO  [STDOUT] Hibernate: select
processins0_.processInstanceId as processI1_344_0_,
processins0_.externalVariables as external2_344_0_,
processins0_.lastModificationDate as lastModi3_344_0_,
processins0_.lastReadDate as lastRead4_344_0_, processins0_.processId as
processId344_0_, processins0_.processInstanceByteArray as
processI6_344_0_, processins0_.startDate as startDate344_0_,
processins0_.state as state344_0_, processins0_.OPTLOCK as OPTLOCK344_0_
from ProcessInstanceInfo processins0_ where
processins0_.processInstanceId=?
20:18:21,342 INFO  [STDOUT] Hibernate: select
processins0_.processInstanceId as col_0_0_ from ProcessInstanceInfo
processins0_ where ? in (select eventtypes1_.element from
ProcessInstanceInfo_eventTypes eventtypes1_ where
processins0_.processInstanceId=eventtypes1_.ProcessInstanceInfo_processI
nstanceId)
20:18:21,358 INFO  [STDOUT] Hibernate: update SessionInfo set dirty=?,
lastModificationDate=?, rulesByteArray=?, startDate=? where id=?
20:18:21,373 INFO  [STDOUT]
****com.datacert.apps.sampleapplication.models.Person71


Milestone output
21:41:34,353 INFO  [STDOUT] Hibernate: insert into ProcessInstanceInfo
(externalVariables, lastModificationDate, lastReadDate, processId,
processInstanceByteArray, startDate, state, OPTLOCK) values (?, ?, ?, ?,
?, ?, ?, ?)
21:41:34,353 INFO  [STDOUT] ********** currentApproverName:null
airline:null
21:41:34,353 INFO  [STDOUT] Hibernate: update ProcessInstanceInfo set
externalVariables=?, lastModificationDate=?, lastReadDate=?,
processId=?, processInstanceByteArray=?, startDate=?, state=?, OPTLOCK=?
where processInstanceId=? and OPTLOCK=?
21:41:34,353 INFO  [STDOUT] Hibernate: update SessionInfo set dirty=?,
lastModificationDate=?, rulesByteArray=?, startDate=? where id=?
21:41:34,353 INFO  [STDOUT] *** inserting:
com.datacert.apps.sampleapplication.models.Person
21:41:34,369 INFO  [STDOUT] Hibernate: update SessionInfo set dirty=?,
lastModificationDate=?, rulesByteArray=?, startDate=? where id=?
21:41:34,369 INFO  [STDOUT] ******** setting approver in rules
21:41:34,369 INFO  [STDOUT] **************approver:null airline:delta
21:41:34,369 INFO  [STDOUT] Hibernate: select
processins0_.processInstanceId as processI1_279_0_,
processins0_.externalVariables as external2_279_0_,
processins0_.lastModificationDate as lastModi3_279_0_,
processins0_.lastReadDate as lastRead4_279_0_, processins0_.processId as
processId279_0_, processins0_.processInstanceByteArray as
processI6_279_0_, processins0_.startDate as startDate279_0_,
processins0_.state as state279_0_, processins0_.OPTLOCK as OPTLOCK279_0_
from ProcessInstanceInfo processins0_ where
processins0_.processInstanceId=?
21:41:34,369 INFO  [STDOUT] Hibernate: select variables0_.processId as
processId1_, variables0_.id as id1_, variables0_.name as formula5_1_,
variables0_.id as id280_0_, variables0_.name as name280_0_,
variables0_.persister as persister280_0_, variables0_.entityClass as
entityCl5_280_0_, variables0_.entityId as entityId280_0_,
variables0_.content as content280_0_, variables0_.TYPE as TYPE280_0_
from VariableInstanceInfo variables0_ where variables0_.processId=?
21:41:34,385 INFO  [STDOUT] Hibernate: delete from
ProcessInstanceInfo_eventTypes where
ProcessInstanceInfo_processInstanceId=?
21:41:34,385 INFO  [STDOUT] Hibernate: delete from ProcessInstanceInfo
where processInstanceId=? and OPTLOCK=?
21:41:34,385 INFO  [STDOUT] Hibernate: select
processins0_.processInstanceId as col_0_0_ from ProcessInstanceInfo
processins0_ where ? in (select eventtypes1_.element from
ProcessInstanceInfo_eventTypes eventtypes1_ where
processins0_.processInstanceId=eventtypes1_.ProcessInstanceInfo_processI
nstanceId)
21:41:34,400 INFO  [STDOUT] Hibernate: update SessionInfo set dirty=?,
lastModificationDate=?, rulesByteArray=?, startDate=? where id=?
21:41:34,416 INFO  [STDOUT]
****com.datacert.apps.sampleapplication.models.Person73
21:41:39,447 INFO  [LoggingFilter] IDLE: both idle

Thanks,
Todd

-----Original Message-----
From: Kris Verlaenen [mailto:Kris.Verlaenen at cs.kuleuven.be] 
Sent: Sunday, January 17, 2010 6:24 PM
To: Rules Users List; Todd Pagni
Subject: Re: [rules-users] Setting a Flow Variable from a Rule

If you have access to the process instance that contains the variable,
you can do 
  ((RuleFlowProcessInstance) processInstance).setVariable(name, value);

Changing the value of an object that has been set as a variable in a
process instance should also be taken into account.  Do you have an
example of where this seems to have been broken in the snapshot?

Kris

Quoting Todd Pagni <todd.pagni at datacert.com>:

> How do you set a flow variable (not global) from inside a rule so it
> is
> available for nodes that follow the rule execution? I cannot seem to
> find this in the doc.
> 
>  
> 
> Previously I had a Person() fact that was also passed into the flow
> as a
> variable, when I modified the fact Person() object it was reflected
> in
> the flow variable, but the latest snapshot seems to have broken this
> so
> I am looking for alternatives.
> 
>  
> 
> 
> Thanks,
> 
> Todd
> 
> 




Disclaimer: http://www.kuleuven.be/cwis/email_disclaimer.htm




More information about the rules-users mailing list