| Previous | Next |  | Contents | Index | Glossary

## Workflow Objects That Do Not Support Versioning

The following Workflow objects do not support versioning:

- Item attributes

- Messages

- Lookups

- PL/SQL code referenced by function activities

When you modify any item attributes, messages, or lookups in the Workflow Builder and save them to the database, the Workflow Loader updates the existing definition of the object. Also, if you modify the existing PL/SQL API for a function activity, the function activity will reference the updated API stored in the database.

As a result, if you modify any of these objects, your changes immediately affect any active work items that reference the object. Plan your changes carefully to ensure that the changes do not cause any backward incompatibility.

> Note: The Workflow Builder does not support the editing of PL/SQL code. PL/SQL code is listed as a Workflow object here solely for the purpose of explaining the consequences of changing the code referenced by a Workflow function activity.

#### Item Attributes

When a work item is initiated, Oracle Workflow creates a runtime copy of each item attribute that is defined for that item type. The Workflow Engine refers to these runtime copies whenever an item attribute is referenced in the PL/SQL code for a function activity in the workflow process.

Adding a new item attribute after work items have been initiated will not affect the active work items. However, these work items will not include the new item attribute unless you specifically create the attribute for them by calling the AddItemAttr() or AddItemAttributeArray APIs. If you also add references to the new item attribute in the existing PL/SQL code within the workflow process, those references may cause errors in active work items that do not include the attribute.

For example, if you change the PL/SQL API for a function activity by calling a Workflow Engine API to communicate with a new item attribute, the function activity will fail for active work items that do not have the new item attribute defined.

You should plan carefully when making any modifications to the existing PL/SQL code within a workflow process to ensure that you do not add references to a new item attribute without also creating the item attribute for active work items that require it. See: PL/SQL Code.

> Note: You can, however, add references to new item attributes in the API that starts a workflow process, without making special provisions for active work items. For example, you can call the SetItemAttribute or SetItemAttributeArray APIs to populate the new item attributes at the start of the process. Active work items will not be affected by such changes, since these work items have already passed through this code.

#### Messages

When the Workflow Engine requests the Notification System to send a message, the Notification System creates a notification attribute in the notification tables for every message attribute. The notification attribute rows contain the variable data that will be token-replaced into the message body, including the subject line and body text, at runtime.

The message body, however, is not copied into the notification tables. Instead, the message body is referenced by the various Notification System APIs at runtime, when the notification is displayed to the user. As a result, any modifications to a message body will affect notifications in active work items that were sent before the change, as well as notifications that are sent after the change.

You can make certain types of modifications to a message body without risking incompatibility errors. These modifications include:

- Adding static text

- Editing static text

- Removing static text

- Removing message attribute tokens

For example, if you add a static sentence such as "Please approve within five days" to a message body, all notifications in active work items will include the additional sentence when you access the notifications. The Notification System can display the modified message body without any errors because no further information is required to resolve the additional sentence.

However, inappropriate modifications, such as adding tokens for newly created message attributes, may cause notifications in active work items to be displayed incorrectly. You should plan your changes carefully to avoid errors.

If you need to add tokens for new message attributes to a message body, you should implement the change by creating a new message rather than by modifying the existing message. You can attach the new message to your existing notification activity without affecting active work items, since notification activities support versioning.

For example, if you create a new message attribute such as Approver Name and you add a token for that attribute in the message body, all notifications in active work items will include the new token when you access the notifications. However, notifications that were sent before the change will not include the new message attribute Approver Name as a notification attribute. The Notification System will not be able to resolve the reference to the new message attribute and will display the token "&APPROVER_NAME" in the notifications instead.

In this example, instead of modifying the original message body, you should create a new message that includes the new message attribute, add the token for the new attribute to the body of the new message, and attach the new message to your notification activity. When you save your changes, the notification activity will be versioned. Then active work items will continue to reference the old version of the notification activity, and the incompatible token will not appear in those notifications.

#### Lookup Types and Codes

Lookup types have the following important uses in Oracle Workflow:

- Determining the possible completion statuses (lookup codes) for workflow activities

- Determining the possible completion statuses (lookup codes) for 'Respond' message attributes.

Inappropriate modifications to lookup types may cause active work items that reference those lookup types to fail.

To avoid errors caused by backward incompatibility, follow these guidelines for lookup types that are referenced by active work items:

- Do not delete lookup types.

- Do not delete lookup codes from existing lookup types.

- Do not add lookup codes to existing lookup types.

If you need to make any of the above changes, you should implement the change by creating a new lookup type rather than by modifying the existing lookup type.

You can attach new lookup types to existing activities without affecting active work items, since activities support versioning. However, you should not attach new lookup types to existing message attributes, since Workflow messages do not support versioning.

The following examples show some errors that can be caused by inappropriate lookup type modifications:

- If you add a lookup code to a lookup type that is referenced by a 'Respond' message attribute, the new lookup code will be available for users to select as a response to a notification. However, previous versions of the notification activity will not have branching logic modeled for the new lookup code. If a user selects the new code, the process will enter an 'ERROR' state.

- If you delete a lookup code from a lookup type that is referenced by a 'Respond' message attribute, users will no longer be able to choose that result code to respond to a notification.

#### PL/SQL Code

Although function activities support versioning, the underlying PL/SQL code does not support versioning, unless you implement versioning for your code yourself. Modifying PL/SQL code without versioning changes the business flow for active work items that reference that code. Inappropriate modifications may cause these work items to fail.

To prevent changes in the PL/SQL API for a function activity from affecting active work items, you should implement the changes by creating a new API rather than by modifying the existing API. You can attach the new API to your existing function activity without affecting active work items, since function activities support versioning.

If you need to modify an existing API and you cannot create a new API instead, you should plan your changes carefully to ensure that the changes do not cause any backward incompatibility.

For example, if you plan to add a lookup code to the group of values that an API can return, you should first ensure that the function activity node has an outgoing transition, such as 'Default,' that the Workflow Engine can follow when the API returns that value. Otherwise, the process will enter an 'ERROR' state when that value is returned. If there is no appropriate outgoing transition, you must implement the change in a new API and update the process to model branching logic for the additional return value.

Also, if you change the existing PL/SQL API for a function activity by calling a Workflow Engine API to communicate with a new item attribute, you should ensure that you also create the new item attribute for active work items. Otherwise, the function activity will fail for active work items which do not have the new item attribute defined.

Calls to any of the following APIs with newly created item attributes as parameters may cause the function activity to fail if active work items do not have the item attributes defined:

- wf_engine.SetItemAttrText

- wf_engine.SetItemAttrNumber

- wf_engine.SetItemAttrDate

- wf_engine.SetItemAttrEvent

- wf_engine.SetItemAttrTextArray

- wf_engine.SetItemAttrNumberArray

- wf_engine.SetItemAttrDateArray

- wf_engine.GetItemAttrText

- wf_engine.GetItemAttrNumber

- wf_engine.GetItemAttrDate

- wf_engine.GetItemAttrEvent

To create copies of a new item attribute for active work items, call AddItemAttr() or one of the AddItemAttributeArray APIs. You can place this call either in a custom upgrade script or in an exception handler.

- Upgrade script - Before you modify your API, write and execute a custom upgrade script that creates and populates the new item attribute for any active work items that reference that API. The following example shows one way to structure an upgrade script.

    		for <each active work item>

    		  begin

    		    wf_engine.AddItemAttr(itemtype, itemkey,

    		                          '<new_attribute_name>');

    		    wf_engine.SetItemAttrText(itemtype, itemkey,

    		                              '<new_attribute_name>',

    		                              '<New attribute value>');

    		  end;

    		end loop;

> Note: Active work items are identified as those items for which WF_ITEMS.END_DATE is not null.

- Exception handler - After the reference to the new item attribute in your modified API, add an exception handler to create and populate the attribute when the attribute does not already exist. The following example shows one way to structure such an exception handler.

`procedure <procedure_name>(`
|  | `itemtype in varchar2,`
|  | `itemkey in varchar2,`
|  | `actid in number,`
|  | `funcmode in varchar2,`
|  | `result in out varchar2)`
`is`
`begin`
| `--`
| `-- RUN mode - normal process execution`
| `--`
| `if (funcmode = 'RUN') then`
|  | `-- your run code goes here`
|  | `null;`
|  |  | `wf_engine.SetItemAttrText(itemtype, itemkey, '<existing_attribute_name>',`
|  |  |  | `'<Existing attribute value>');`
|  |  | `begin`
|  |  |  | `wf_engine.SetItemAttrText(itemtype, itemkey, '<new_attribute_name>',`
|  |  |  |  | `'<New attribute value>');`
|  |  | `exception`
|  |  |  | `when others then`
|  |  |  |  | `if (wf_core.error_name = 'WFENG_ITEM_ATTR') then`
|  |  |  |  |  | `wf_engine.AddItemAttr(itemtype,itemkey,'<new_attribute_name>');`
|  |  |  |  |  | `wf_engine.setitemattrtext(itemtype, itemkey, '<new_attribute_name>',`
|  |  |  |  |  | `'<New attribute value>');`
|  |  |  |  | `else`
|  |  |  |  |  | `raise;`
|  |  |  |  | `end if;`
|  |  | `end;`
|  | `-- example completion`
|  | `result := 'COMPLETE:';`
|  | `return;`
| `end if;`
| `--`
| `-- CANCEL mode - activity 'compensation'`
| `--`
| `-- This is in the event that the activity must be undone,`
| `-- for example when a process is reset to an earlier point`
| `-- due to a loop back.`
| `--`
| `if (funcmode = 'CANCEL') then`
|  | `-- your cancel code goes here`
|  | `null;`
|  | `-- no result needed`
|  | `result := 'COMPLETE';`
|  | `return;`
| `end if;`
| `--`
| `-- Other execution modes may be created in the future. Your`
| `-- activity will indicate that it does not implement a mode`
| `-- by returning null`
| `--`
| `result := '';`
| `return;`
`exception`
| `when others then`
|  | `-- The line below records this function call in the error system`
|  | `-- in the case of an exception.`
|  | `wf_core.context('<package_name>', '<procedure_name>',`
|  |  | `itemtype, itemkey, to_char(actid), funcmode);`
|  | `raise;`
`end <procedure_name>;`

### See Also

Item Attributes

| Previous | Next |  | Contents | Index | Glossary