Variables – Process and Service

As an instance of a process executes, that process is going to have data maintained as part of its state during its complete life. The data may be input into the process when it starts or may be calculated or entered as the process progresses through its life.

Variables are used to hold the state data associated with an instance of a process. Variables are "named" entities which have associated data types. Variables occur in two distinct categories of places in IBPM. The first is the set of variables which can be defined in a BPD. These variables have a scope of the entire instance of the process. Variables are also constrained by the process in which they live. Variables in one process instance can't be accessed in another process (without an explicit passing of their values). A change to a variable in one activity will be seen in subsequent activities.

The other place variables can be defined is within a Service implementation. These variables exist for the life of the Service and are no longer available after the service completes.

Variables can be defined with a qualifier of input, output or private. Input variables have their values passed into a process or service when that process or service is initiated. Output variables have their values returned from a process or service when it completes and private variables only have scope within a process or service and are deleted when they end.

When a variable is created, it can be addressed from within JavaScript with the prefix:

tw.local.<variable name>

(Note: This prefix tw.local is used so frequently that the JavaScript editor has a special shortcut for that called "twl". If you enter twl and then CTRL+Space for content assist, the twl entered characters are changed to tw.local.)

When a variable is defined, it is given a name and other attributes including:

The data types initially supplied available include:

These data types come from the System Data toolkit which is always present within the environment.

When a new variable is defined, it can be declared as having a default value. What this means is that an instance will be created and will already have a value without having to explicitly perform a subsequent assignment to it.

System of Record data vs Business Intelligence data

Let us take a few minutes to think about the data used and produced by a process instance. In my opinion, this data can be split into two logically distinct categories. These are "System of Record data" (SOR) and "Business Intelligence data" (BI).

SOR data is information that can not afford to be lost once the process has ended. It is typically used by other applications in the future. As an example, imagine a process which books a seat on an airplane for a future trip I plan to make. It would be very wrong if I turned up at the airport three weeks from now and found that there was no record of my booking. BPM is not a repository for SOR data. Instead, BPM could be responsible for causing new SOR data to be created or existing SOR data to be updated. The SOR data is maintained by systems outside BPM such as a database or another application.

BI data is information that could, in principle, be lost without damaging the operation of your business. This data is used to examine how your processes performed in the past. It includes times, paths, people, decisions and data relevant to those decisions. Its primary purpose is to provide the capability to perform business analytics. If it were lost, no customers would be upset, no monies would be lost, no corrective actions need be performed … the worst that would happen is that you would be unable to ask questions on how your processes performed in the past. IBM BPM can record BI data through the Performance Data Warehouse (PDW) architecture.

Creating new Data structures

The data types supplied with IBPM are important and useful but as we start to model our business processes we will commonly find that we want to create new data structures. New data structures can also be created which can be composed of fields (also called parameters). These new data structures will be used to represent different types of logical data such as "A Customer" or "A Loan".

In the Behavior section of the data type editor, there are two choices:

When a complex type variable is created, it must be initialized before it can be used. This can be done through JavaScript with the code:

tw.local.myVariable = new tw.object.ComplexType();

A similar story is also true for data of type list:

tw.local.myListOfStrings = new tw.object.listOf.String();

Simple Types

The Simple Type allows us to place constraints on certain simple data types.

Simple type – String

Here we can place length restrictions on the string. This includes either a fixed length or a minimum/maximum length.

Simple type – Integer

Simple type – Decimal

Simple type – Date

Simple type – Time

Simple type – Selection

Business Object Types

A Business Object is commonly used to describe a series of attributes that apply to a concept being worked upon in a process. Consider the concept of a "Customer". A Customer has many attributes including name, address, payment info, purchase history and perhaps much more. We can define the data type known as Customer by creating a new data type within IBPM PD.

A new data type can be created from the Data entry in the list and selecting Business Object.

Once selected, a dialog window appears asking us to name the new data type we are creating. In this example, we have called our new data type "Customer":

Once the data type has been created, the fields of the new structure may be defined. Interestingly IBPM calls what I call field "Parameters". Some products call such data entries "fields", some call them "attributes", others call them "properties" … so why should we not allow IBPM to call them "Parameters".

An arbitrary number of parameters can be added to the structure by pressing the "Add" button. When a parameter is added, its name and data type can be defined. The data type of a parameter can itself be a complex type allowing for a tree like structure to be created. The parameter can also be flagged as a "List" allowing the one parameter to hold zero or more values.

When a variable type is created, that type is available to all artifacts within the defined Process Application. The type can alternatively be defined within a Toolkit and that toolkit re-used across multiple Process Applications. Creating a Toolkit of data types used across your multiple projects is a good idea.

List Variables

A variable can be defined as a list of some data type. Take care to realize that an IBM BPM List is not the same as a JavaScript array. The IBM BPM List data type is mapped to a much richer/different set of semantics. The IBM BPM List data type has the notion of a set of selected items from within the list. This means that given a List, we can also ask that list "Which (if any) items in that list has the property called 'selected'?". This becomes very useful when considering UI based functions.

The List variable has the following operations and properties defined upon it.

A common mistake that is made by BPM programmers using lists within JavaScript is to create the list variable but neglect to create the entries within the list.

For example:


tw.local.myVar = new tw.object.listOf.MyBO(); tw.local.myVar[0].fieldA = "Hello";


tw.local.myVar = new tw.object.listOf.MyBO(); tw.local.myVar[0] = new tw.object.MyBO(); tw.local.myVar[0].fieldA = "Hello";

A list variable tracks which values are "selected". An algorithm to remove selected items, the following snippet may be used:

for (var i = 0; i < tw.local.myList.listLength; i++) { if (tw.local.myList.listIsSelected(i)) { tw.local.myList.removeIndex(i); i--; } }

To add an item to the list, the "insertIntoList()" method can be used. It is not a "replace" item function but instead will move other entries up as needed.

Q: If I remove an element from the list using removeIndex, is the selected set "adjusted"?

Setting defaults on variables

When a variable is defined in a service or BPD as either input or private, a default value can be provided. The default provides an initial value for private variables and a default value for input variables that are not supplied. The default value is set in the variables tab if the "Has Default" check box is selected. If selected, the text area provides a place in which the default values can be placed. The appearance of the entry of the default values changes depending on whether or not the PD is in advanced mode. If it is in advanced mode, JavaScript can be entered as long as it results in a value for the variable.

Making variables search-able

Process Portal can be used to find instances of processes based upon the values contained in variables within the process. Because IBPM has to do more work to index the values of the variables that are to be looked up, this feature has to be enabled on a variable by variable basis. In the declaration of variables, there is an option to enable searching for Business Data.

Defining and using shared objects

From IBM BPM v8 onwards, a capability called Shared Objects was added. Shared Objects have the ability to flag a Business Object definition as being a Shared Object. See the following image:

Note that Business Objects flagged as shared have a "green" icon as opposed to the normal "purple" icon of non-shared business objects:

|| ||Non-Shared Business Object| ||Shared Business Object|

Once flagged, variables created of this BO type are now passed by reference as opposed to passed by value around the environment. What this means is that multiple processes or parallel steps within processes can "see" and "update" the variable simultaneously. If we wish to have multiple processes work with the shared object simultaneously, then we need to pass a "key" that can be used to access the variable in a different process.

This is starting to get subtle so let us try and break this down. Consider the previous screen shot which shows the creation of a new Business Object type called "MySharedBO". Now consider an instance of a process which declares a variable of type "MySharedBO".

We should be able to easily imagine an instance of the MySharedBO Business Object being "held" somewhere for future reference. Imagine that we wished to have a second process leverage the same shared object. The second process can declare a variable of type MySharedBO but … to get a reference to the object, will have to execute:

tw.local.myShared2 = new tw.object.MySharedBO(keyValue);

but wait … where did the "keyValue" parameter come from?

On the original reference to the Business Object, we can access its "key" value with:

var keyValue = tw.local.myShared1.metadata("key");

The 'metadata("key")' method returns a string representation of the key to that shared object. Note that "key" in this call is actually an explicit keyword (i.e. the string with value "key") and not a variable name.

When a change is made to the data contained within the Shared Object that data is written to a database behind the scenes. Only when the data is written, will the data be able to be seen by a partner. The data is written when a service that modifies it completes or when an explicit call to the save() method (found on the business object) is called.

Take care with unusual conditions such as the following:

In the first activity, we create a shared business object and in the second we modify it. However, since these are two script activities in the BPD, they don't actually run as separate steps but run sequentially (for performance reasons). That means that the data isn't written after the first change but at the end of the second. If we wanted to experiment with forcing data to be written we can insert a zero delay timer between the activities:

The data associated with the Shared Object is associated with a process instance that created it. When the process instance data is cleared, so is the Shared Object.

One important area that requires further consideration is when a process sees the changes that another process may have made to the data. The answer is not quite what one may trivially expect. Imagine two process instances, P1 and P2. P1 creates an instance of a Shared Object and sets its values. P2 then also creates an instance referencing the key from P1. Now P2 changes a value in the data and executes a save(). What does P1 now see?

The choices would appear to be:

The answer is "it depends".

This is the concept of the "latest version of the data in the Shared Object". This is what will be used when either a new instance of the Shared Object with the given key is created or an existing instance is re-loaded with an explicit load() call. So if P1 executes a load(), it will always get the latest data.

A reload of the data within P1 happens automatically when a step in a process is transitioned or when a task is woken up. However, within the context of a single straight through service, the values of the variable will not change unless it is explicitly re-loaded. The transition from step to step in a process is an implicit re-load as is the awakening of the task.

Save Service definitions

If we think about a shared business object as being a copy of a common business object as opposed to a reference to a common area of storage, we will be closer to understanding how shared business objects actually work. There will come a point after you have made changes to your copy of the shared business object when the changes are considered complete. This may happen implicitly or explicitly. For example, after a service makes changes and is about to return any changes made within the shared business object are persisted.

In reality, a shared business object is "backed" by a row in a database table so when we finalize our changes they are essentially over-writing or updating what was previously in that row.

When working with shared business objects we have the ability to define a BPM service that is automatically invoked when a request to save a shared business object occurs but before the actual update of the data mechanically happens. Within this service, we have the opportunity to change or update the data to be saved as well as reject the changes themselves. This is a powerful capability and one that we need to spend a little time discussing.

To leverage this capability, we should look to the Business Object definition. In the behavior section of the Business Object editor we will find a location to supply either an existing service or create a new one:

If we ask to create a new one, a service is created which has the correct signature for our needs. The signature of such a service looks as follows:

Let us now look at each of the parameters in turn:

object – The current value of the business object that is to be saved. This is what the local logic thinks is going to be saved to the database as the new value of the shared business object.

baseVersion – The value of the shared business object that represents the state of the object before any changes were made to it. This may be null if this is the first creation of the business object.

lastestVersion – The value of the shared business object that is the current version that is contained within the database. This may be different from the baseVersion if some other service or process has performed an update after the initial read of the baseVersion but before the saving of changes made in this session.

changes – A list of changes that have been made to the variable that identify how it differs between the baseVersion and the current version. Each record in this list is an instance of a BPMBOPropertyChange object which contains the following fields:

For output, the service may return a list of validationErrors. These are logic defined indications that the save of the shared business object should be prevented. The validation errors indicate the reasons. This variable is a list of BPMBOValidationError data types where each instance of those contains:

Within your service, you can also update the value of the business object before save. This allows automatic calculation of values to be performed.

Let us look at an example of a business object save service. Let us imagine a business object which contains the following details:

If we associate a save service with this shared business object type, then the service will be invoked whenever a change is made to the data. That includes initial creation of the object.

Here is an example service that will log the data associated with the change:"object - " + tw.local.object.toXML()); if (tw.local.baseVersion == null) {"baseVersion – null"); } else {"baseVersion - " + tw.local.baseVersion.toXMLString()); } if (tw.local.latestVersion == null) {"latestVersion – null"); } else {"latestVersion - " + tw.local.latestVersion.toXMLString()); } if (tw.local.changes == null) {"changes – null"); } else {"changes - " + tw.local.changes.toXMLString()); }

Process instance Global Data

The utilization of shared business objects can be leveraged to provide us a technique for creating and using process instance global data. Consider a simple process consisting of a BPD that calls a service. In order for the service to operate, it needs data. We normally associate that data as input and output parameters of the service and bind those to variables in the BPD. There is, however, an alternative story. In classic programming, we can create global variables that have a scope that is addressable by multiple code functions without having to explicitly pass them. We could talk about the philosophical correctness of such notions including constraining scope and the injection of tight coupling between modules but I want to avoid that just now. What if we decided that for some reason we wanted to assume that when a service runs, it should be able to see a variable called "myData" that has been created in the BPD that calls the service. We want to do this without explicitly passing the variable into the called service. How can we do this?

One solution would be to use shared business objects. In the BPD, the data type that is used for "myData" could be defined as a shared business object. We could then obtain the key for that object and save the key as a BPD private variable … for example called "dataKey". When the service is called, the service will be running in the context of its calling process. We can then use the function called:


to obtain the TWProcessInstance object representing the calling process. From there, we can use the "businessData" property which is a map of value in the process. For example, in the service we could code:

var myData = new tw.object.Shared1(tw.system.currentProcessInstance.businessData.get("dataKey"));

And now myData would be a reference to the BPD level shared object. If we change the values contained in myData, we should save them with:;

BPD Variables and Service Variables – Mapping

A Business Process Definition has variables associated with it. Some variables might be input to the process, some may be output from the completed process and some may be local variables only visible to the process.

In addition to the a BPD having variables, so too can a IBPM Service. Just like a BPD, a IBPM Service has input, output and local variables. These are defined in the definition of the IBPM Service.

A IBPM Service is usually invoked from within the context of a BPD through an Activity node. When the node is defined, it is associated with a IBPM Service definition. If we think about this for a moment, we see that the IBPM Service has some input variables that it is expecting to contain data and will return some output variables that make data available to the process as a whole. These variables in the IBM service need to be "mapped" to variables that are in scope within the BPD that is calling the service.

When an Activity is selected in the BPD editor, the properties section shows a Data Mapping tab. Selecting this shows the expected input variables to the associated IBPM Service as well as the generated output variables. These can then be mapped to variables within the current BPD. The icon beside the "boxes" ( )provides for a smart search of the defined variables so we do not need to remember the JavaScript variable names.

If a variable is defined as a complex type, it will need to be initialized before values can be assigned to it. Its initial value is "null" which has no fields. A good way to achieve initialization is to check the has default check box in the data type definition.

Variable identity and UUID

Imagine you create a new Business Object type called "MyBO". What is the identity of that Business Object type? As you might imagine, there is more to this simple question than meets the eye. The normal way of thinking is that if I create a data type called "X" then it has an identity of "X". Unfortunately, IBM BPM doesn't think that way. Internally within the heart of the product, all artifacts (including all data types) are given a generated UUID value. It is this opaque UUID that the product uses to track references to data types.

To illustrate, consider the following Human Service definition which has an output parameter called "myBO" of data type "MyBO":

The Human Service definition (called HS1) can be read as:

"This service returns an output called 'myBO' of type 'MyBO'".

However, this is only an illusion. The way the product really thinks of this is:

"This service returns an output called 'myBO' of type 'guid:7b9691c16dd21a42:1e6925ca:142dd70d25a:-7ffa'"

Hmm. That is quite a difference. If we switch on advanced mode in PD and then look at the definition of the business object, we can see that UUID there:

Normally, I wouldn't try and uncover internals knowledge such as this as it is usually irrelevant to the model and used of the BPM product itself however, there are some ugly ramifications associated with this implementation story.

As a thought process, consider the following:

Are we now consistent? It would seem so, we have a business object called MyBO which contains all the fields we want. Unfortunately, we are broken.

In step 2, when we create a Human Service that returned a variable of type MyBO, the Human Service actually defined that it returned a data type of a UUID. That UUID was associated with the data type created in step 1. When we performed step 4, a brand new UUID data type was created that is not the same as that of step 1.

We end up with the Human Service error showing:

If we hovered over the error we would see:

But yet if we examined the list of data types, we would see that MyBO is a defined data type.

The fix would be to remap the variable type to the new MyBO definition. To most folks (including myself) this is an odd situation to be in.

The moral of the story is to be very careful with the concept of deleting and recreating data types. Deleting something and then recreating it is not the same as modifying it. This story also comes into play when you think that you can move data types into toolkits.

Exposing Business Data for Searches

Imagine that we have hundreds (perhaps thousands) of process instances running handling orders for customers. If a customer calls in and asks "What is the status of my order #1234?" how can we find the process associated with this?

When process variables are defined in IBPM, we have an opportunity to flag them as being available in Business Data Searches. This means that we can execute searches using the exposed names and values of variables in a process. For example, if a process has a variable called "orderNumber" and we exposed that for searching, we can now execute a search for process instances where "orderNumber = 1234".

Accessing variables from JavaScript

It is common to want to read or write the values of variables from within a JavaScript environment. When a variable is defined at the BPD or service level, it is available within that BPD or service within the JavaScript scope of:


The IBPM PD commonly provides entry assist to show you the names of the in-scope variables that can be used in a JavaScript fragment. Note that the entry assistance accessed by CTRL+Space in the editor can be used to substitute the characters "twl" for the string "tw.local.".

List variables can be accessed using square bracket notation with an index value starting at 0. When assigning to a list, if an index value is used that is greater than the size of the list, this is acceptable. To make this clear, imagine a list with two existing entries which would be [0] and [1]. If we assign to the list with an index of [3], this would produce an entry for [2] of data type ANY and no value.

Environment Variables

Instead of hard-coding values in a process, we may wish to externalize these values and re-use them across our solution. IBPM PD allows us to define environment variables in either Process Applications or in Toolkits. Once defined in there, they can then be referenced in the solution.

The environment variables section can be accessed from the Process App Settings within the Environment tab:

Variables defined in the Process Application can be accessed as:

tw.env.<Env Variable Name>

Variables defined in a Toolkit can be accessed as:

tw.env.toolkit.<Toolkit Name>.<Env Variable Name>

Note: When setting initial values of environment variables within Process Designer, make sure that you do not surround the values with quotes. There is no need. The values entered are already strings. For some reason, a common error is that folks are adding quotes which adds the quotes themselves into the value of the string:

The values of the environment variables can be changed through the Process Admin Console.

After starting it up, select the Installed Apps button:

Next, select the application who's environment variables are to be changed. A list of the environment variables and their current values can then be seen:

The environment variables default values can be based on the setting of the environment.type attribute set in the used when IBPM is installed.

To make changes to environment variables, one must be a member of the administrators group.

Exposed Process Values (EPVs)

Consider a business process that utilizes some business data value such as the current tax rate or the interest rate on loans. This value is obviously not a constant as it may change over time. What we want is a way to supply such values to processes while at the same time making them easy to modify as needed. The concept of Exposed Processes Values (EPVs) is the IBPM solution.

An EPV is a named container that holds one or more variables where the values of those variables can be defined through the Process Administration console.

An EPV is defined within a Process Application or Toolkit from the Data catalog in the library.

When the wizard appears to create a new EPV, a name can be supplied for it.

Once created, the editor provides a rich set of settings for it. At its basic level, we define a set of one or more variables and give each variable a name, data type and default value.

Updates and access to the EPV is performed through the Process Admin Console. Only those users to whom the EPV is exposed can modify its value. The Exposed to section names a group of users who are allowed to manage the EPV.

The Feedback E-mail contact provides the email address of the "owner" of this EPV. This allows users to contact the owner for questions and requests.

In a BPD or service definition, within the variables section, an EPV can be linked or associated with the BPD or service:

tw.epv.[EPV Name].[EPV Variable Name]

can be used to refer to those values.

See also:

Pre and Post Assignments

Associated with an activity element is the concept of pre and post assignments. These sections of the activity definition allow for updates of variables prior to executing the core of the activity and also to allow for updates immediately following the core of the activity.

The number of pre and post assignments (if any) on an individual activity is configurable.

There have been a number of discussions on the value and appropriateness of pre and post assignments. The questions arise when thinking about readability and maintainability of a solution that uses this technique. The markers added to an activity to indicate that it has pre or post assignments are small and easily missed. There is a school of thought which says that this capability should not be used often and instead, explicit steps be added to the process diagram to achieve the same effect.

Variables and XML

Each complex variable has an XML representation. To examine this, let us initially look at a complex data type called Type1 that looks as follows:

This structure contains three fields called "a", "b" and "c". If we create an instance of this variable and execute tw.system.serializer.toXml method, we get the following:

<variable type="Type1"> <a type="String"><![CDATA[value for a]]></a> <b type="Boolean"><![CDATA[false]]></b> <c type="Integer"><![CDATA[123]]></c> </variable>

Breaking this apart, we see an element called <variable> as the root with type attribute that names the data type of the variable as a whole. The nested elements are named after the fields within the structure again using the type attribute to define the data type of the fields.

Given an XML representation of the data, we can convert back to a variable instance with the method called:


This takes either a String or XMLElementobject as a parameter and returns a new Object instance.

For variables defined as lists, the structure is a little different.

<variable type="Item[]"> <item type="Item"> <name type="String"><![CDATA[Item1]]></name> <quantity type="Integer"><![CDATA[10]]></quantity> </item> <item type="Item"> <name type="String"><![CDATA[Item2]]></name> <quantity type="Integer"><![CDATA[20]]></quantity> </item> </variable>

In the Data Type definition, there are properties for the XML serialization:

Using the fromXml and toXml methods together, we can create a copy of an existing variable. For example:

var newBO = tw.system.serializer.fromXml(tw.system.serializer.toXml(oldBO));

Using Variables

Since variables in IBPM are available within JavaScript then any JavaScript functions that execute on such variables can be used.

If a variable is used to represent a business object, remember that the variable is a reference to that data and not its value. For example, if we have code that looks as follows:

var x = new tw.object.MyDataType(); var y = x;

Then the variable y is actually a reference to the same object as the variable called x and importantly not a copy. Changing a field in x will cause the exact same field in y to be also changed. If the desire is to explicitly make a copy of a variable, consider using the IBPM provided XML serializer and de-serializer. For example:

var x = new tw.object.MyDataType(); var temp = tw.system.serializer.toXml(x); var y = tw.system.fromXml(temp);

On a broader scale, there is a question on what happens when a business object is passed from one entity to another (for example, a process to a sub-process)? In computer science there is the concept of pass-by-value vs pass-by-reference. With pass-by-value, a copy of the variable is passed and hence chances to that copy do not affect the value of the original variable. With pass-by-reference, a reference (pointer) to the original variable is passed. This means a change to the content of one variable immediately affects the value of the other variable. In IBPM both pass-by-value and pass-by-reference are used in different circumstances.

|| |Scenario|Passing mechanism| |Process invokes a sub-process|Pass-by-reference| |Process invokes a service|Pass-by-value| |Service invokes a nested service|Pass-by-reference|

When assigning a value to a Business Object, one can use the JavaScript style of definition. For example:

tw.local.myData = { a: "My A Value", b: 123, c: 3.141, d: { x: "X Value", y: "Y Value" } };

would work for an appropriate definition of the data type of myData. The use of this technique can dramatically simplify data assignment.

Determining the type of a variable

On occasion, you may find that you have a local JavaScript variable and not know what type it is. You can dynamically determine its type. See the following example:

var myDate = new tw.object.Date();"The data type of the object is: " +, -1));

The case of the mysteriously changing variables

Consider the following story:

First, imagine a data type called "MyBO" that has three fields:

Now imagine a process called "LinkedProcess1" which looks as follows:

The parameters to this process are:

What this process does is take an instance of "MyBO" as input, set the value of property "a" to say that it is "Linked Process 1" that set it and finally create a task that shows the content of the MyBO data type.

If we ran it by itself, an example of what the task would show is:

Now imagine a second process called "LinkedProcess2". It looks like:

It is identical to "LinkedProcess1" with the exception that it sets the "a" property to say that we are in "Linked Process 2".

Now ... here comes the next part ...

Imagine one last process called "MyProcess" which looks like:

This process has a single "MyBO" variable which is passed as input to two parallel linked processes. These are mapped to "LinkProcess1" and "LinkProcess2".

When I run this process, as expected, I see it block waiting on two tasks:

And I see two tasks available to be worked upon:

Now I open the task for "Linked Process 1" ... and here is what I see:

So far, all as expected.

Now I open up the task for "Linked Process 2" ... and here is what I see:

Do you see it? :-)

The "a" field has the wrong value!!! It should say:

So .... what happened?

The answer can be found in the IBM BPM documentation found here:

Here is what caught my eye:

When we call from one process to another as a link, the variable is passed by reference and not by value (a copy).

What this means ... is that our BPM process called "MyProcess" (see above) ... is logically the same as:

And if we look closely at this diagram, we see that the two marked activities BOTH set the same business object instance field to two different values ... in parallel and since one of them will run before the other in reality, the last one executed will set the single value ... and it is that single value that is shown in the Coaches.

With this understanding in mind, we can now see how to avoid the problem ... have two business objects ... one for "Linked Process 1" and one for "Linked Process 2" ... and don't share the same business object between both.

No Comments
Back to top