Are you sure you want to change system routine?

Is there any particular reason why you want to replace Cache for IRIS in code?

Anyway, is IRISLIB database writable?

Here's how you can make database writable.

  • Open System Management Portal
  • Go To: Menu (upper right corner) -> Databases
  • Choose database you want to modify
  • Set/remove ReadOnly flag
  • Saave

It's really not recommended for IRISLIB.

Some questions/notes:

1. Why are you not using relationships?

2. If you have an object, which references another object in a property and you save a base object all it's properties-objects are also saved automatically. Have you thought about setting all references before save and after that only calling %Save() once?

3. I'd really recommend against relying on auto-incremental ID matches. They are NOT guaranteed to be equal.

4. The answer to your original question depends on where the failure was. %OnAfterSave is in transaction and is rolled back. However $Increment  used to get hew IDs is not rolled back (as per documentation).

If you want it stored, make it triggered computed like this:

Property LabCode As %Library.String(MAXLEN = 64) [
  SqlColumnNumber = 5,
  SqlComputeCode = { set {*}= $EXTRACT({LabName},0,3)_" "_{LabID}},
  SqlComputed,
  SqlComputeOnChange = LabName ];

Docs.

Note that it wouldn't recalc LabCode values for existing rows. If you need that, trigger recalculation with trivial update.

Use {%%ID}.

Here's an example:

Class util.Calc Extends %Persistent
{
Property calc As %String [ Calculated, SqlComputeCode = {set {*} = {%%ID}}, SqlComputed ];

/// do ##class(util.Calc).Test()
ClassMethod Test()
{
    set obj = ..%New()
    set sc = obj.%Save()
    do ..AllFunc().%Display()
}

Query All() As %SQLQuery
{
SELECT *
FROM util.Calc
}
}

Calling:

do ##class(util.Calc).Test()

Returns:

ID      calc
1       1

Docs.